Skip to content

Conversation

@adaam2
Copy link
Member

@adaam2 adaam2 commented Jan 30, 2026

Summary

  • Support React 16.8+ and React 17 in @gram-ai/elements by polyfilling React 18 APIs (useSyncExternalStore, useId, useInsertionEffect, startTransition, useTransition, useDeferredValue)
  • Ship a reactCompat() Vite plugin at @gram-ai/elements/compat that handles bundler-level shimming for named imports in third-party dependencies (zustand, @assistant-ui/react, etc.)
  • Runtime patching via compat.ts covers the library's own code; the Vite plugin covers transitive dependencies that use named imports from react
  • Polyfill logic lives in a single shared module (compat-shims.ts) used by both the runtime patcher and the bundler shim

React 16 app test:

CleanShot 2026-02-02 at 12 16 55@2x

Usage (React 16/17)

import react from '@vitejs/plugin-react'
import { reactCompat } from '@gram-ai/elements/compat'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [react(), reactCompat()],
})

Files

File Purpose
elements/src/compat-shims.ts Shared polyfill factory functions
elements/src/compat.ts Runtime patching of React module object
elements/src/react-shim.ts Bundler-level shim (re-exports React with polyfills)
elements/src/compat-plugin.ts Vite plugin that sets up resolve aliases
elements/package.json Added ./compat subpath export
elements/README.md React compatibility docs
elements/README.typedoc.md React compatibility docs

Test plan

  • pnpm build succeeds, dist/compat-plugin.js and dist/react-shim.js produced
  • pnpm test passes (15/15)
  • pnpm lint passes
  • Built compat-plugin.js has no runtime vite dependency
  • react-shim.js imports shared compat-shims chunk (no duplicated polyfill code)

🤖 Generated with Claude Code

Add compatibility shims that polyfill React 18 APIs (useSyncExternalStore,
useId, useInsertionEffect) so elements can run on React 16.8+. These are
used by transitive deps (zustand, assistant-ui, react-query).

- Lower peer dependency range from >=18 to >=16.8
- Add compat.ts with inlined polyfills (no extra npm dep)
- Import compat module first in index.ts entry point
- Add unit tests for the compat module
- Add integration test apps for React 16 and 17 with shared code

Based on: https://www.assistant-ui.com/docs/react-compatibility

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@adaam2 adaam2 requested a review from a team as a code owner January 30, 2026 17:45
@vercel
Copy link

vercel bot commented Jan 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gram Ready Ready Preview, Comment Feb 2, 2026 4:16pm
gram-docs-redirect Ready Ready Preview, Comment Feb 2, 2026 4:16pm

Request Review

@changeset-bot
Copy link

changeset-bot bot commented Jan 30, 2026

🦋 Changeset detected

Latest commit: 3ffed70

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@gram-ai/elements Minor
dashboard Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional flags.

Open in Devin Review

The bundler-level shim re-exports React with polyfilled hooks
(useSyncExternalStore, useId, useInsertionEffect) and
__SECRET_INTERNALS for react-dom compatibility. Vite resolve.alias
redirects react to shim to real React package per test app.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@speakeasybot
Copy link
Collaborator

speakeasybot commented Jan 30, 2026

🚀 Preview Environment (PR #1422)

Preview URL: https://pr-1422.test.getgram.ai

Component Status Details Updated (UTC)
✅ Database Ready Existing database reused 2026-02-02 16:20:21.
✅ Images Available Container images ready 2026-02-02 16:20:04.

Gram Preview Bot

Session server now starts automatically with 'npm run dev' via a Vite
plugin that spins up the server on a free port and proxies /chat/session
requests to it. No separate server process needed.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View issue and 8 additional flags in Devin Review.

Open in Devin Review

Replace the proxy-based session server with direct Vite middleware
that calls the Gram API. Force-read .env.local to override system
env vars that Vite's loadEnv gives precedence to.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
The React 16/17 test apps brought @types/react@16 and @types/react@17
into the workspace, causing TS2786 JSX type errors in the client.
These apps are standalone and should not be workspace members.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
These integration test apps for React 16/17 were causing issues in CI
and need rethinking for local dev (CORS proxy, port handling). Removing
for now to unblock the PR.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View issue and 11 additional flags in Devin Review.

Open in Devin Review

Export a self-contained Vite plugin at @gram-ai/elements/compat that
shims React 18 APIs (useSyncExternalStore, useId, useInsertionEffect)
via a virtual module, so consumers on older React versions only need
to add one line to their Vite config.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Extract polyfill factories into compat-shims.ts, used by both compat.ts
(runtime patching) and react-shim.ts (bundler-level shim). The Vite
plugin now points to the physical react-shim.js via resolve.alias
instead of inlining a JS string.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Wrap getSnapshot() calls in try-catch matching the official React shim
- Add polyfills for startTransition, useTransition, useDeferredValue
  which are undefined on React 16/17

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View issue and 14 additional flags in Devin Review.

Open in Devin Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview Spawn a preview environment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants