pnpm-react-types-monorepo-mismatch
Fix for "X cannot be used as a JSX component" TypeScript errors in pnpm monorepos. Use when: (1) Build fails with "ForwardRefExoticComponent is not a valid JSX element type", (2) Component worked before but now fails type checking after adding a new package, (3) Error mentions ReactNode or ReactElement type incompatibility, (4) Multiple packages in monorepo have different @types/react versions. The fix uses pnpm overrides to force a single React types version across all packages.
SKILL.md
| Name | pnpm-react-types-monorepo-mismatch |
| Description | Fix for "X cannot be used as a JSX component" TypeScript errors in pnpm monorepos. Use when: (1) Build fails with "ForwardRefExoticComponent is not a valid JSX element type", (2) Component worked before but now fails type checking after adding a new package, (3) Error mentions ReactNode or ReactElement type incompatibility, (4) Multiple packages in monorepo have different @types/react versions. The fix uses pnpm overrides to force a single React types version across all packages. |
name: pnpm-react-types-monorepo-mismatch description: | Fix for "X cannot be used as a JSX component" TypeScript errors in pnpm monorepos. Use when: (1) Build fails with "ForwardRefExoticComponent is not a valid JSX element type", (2) Component worked before but now fails type checking after adding a new package, (3) Error mentions ReactNode or ReactElement type incompatibility, (4) Multiple packages in monorepo have different @types/react versions. The fix uses pnpm overrides to force a single React types version across all packages. author: Claude Code version: 1.0.0 date: 2026-01-23
pnpm React Types Monorepo Mismatch
Problem
TypeScript build fails with misleading errors like "'Card' cannot be used as a JSX component"
when different packages in a pnpm monorepo have different versions of @types/react.
Context / Trigger Conditions
- Error message:
'X' cannot be used as a JSX component. Its type 'ForwardRefExoticComponent<...>' is not a valid JSX element type. - Variant:
Type 'ReactNode' is not assignable to type 'ReactNode'. Type 'ReactElement<unknown, string | JSXElementConstructor<any>>' is not assignable to type 'ReactNode'. - When it happens: After adding a new package to a monorepo, or when packages have divergent dependencies
- Misleading aspect: The error suggests the component itself is wrong, but the actual issue is type version mismatch
Solution
Step 1: Diagnose the version mismatch
pnpm ls @types/react --depth=0 -r
Look for different versions across packages, e.g.:
package-a: @types/react 18.3.27
package-b: @types/react 19.2.7
Step 2: Add pnpm overrides to root package.json
{
"pnpm": {
"overrides": {
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0"
}
}
}
Use the version that matches your actual React version (React 18 → @types/react@^18.0.0, React 19 → @types/react@^19.0.0).
Step 3: Reinstall dependencies
pnpm install
Step 4: Verify the fix
pnpm ls @types/react --depth=0 -r
# All packages should now show the same version
pnpm build
Verification
pnpm ls @types/react --depth=0 -rshows identical versions across all packages- Build completes without JSX component type errors
Example
Before (in root package.json):
{
"pnpm": {
"overrides": {
"next": "^15.5.9"
}
}
}
After:
{
"pnpm": {
"overrides": {
"next": "^15.5.9",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0"
}
}
}
Notes
- This commonly occurs when using Remotion (which pins older React types) alongside a Next.js app using React 19
- The same pattern applies to npm workspaces using
overridesand yarn usingresolutions - Always match the types version to your actual React runtime version
- Consider adding a note in the monorepo README about this override for future maintainers