[BUG] @types/react is not declared as a peer dependency, breaking types under strict linkers
2. Describe the bug
motion and framer-motion declare react and react-dom as optional peer dependencies, but not @types/react. Their type files import React:
import * as React from "react"Under a strict, non-hoisted node_modules, those type files cannot resolve React's types. Every motion component's props degrade and TypeScript reports:
error TS2607: JSX element class does not support attributes because it does not have a 'props' property3. IMPORTANT: Provide a CodeSandbox reproduction of the bug
Not possible here, and I want to be upfront about that rather than link something that does not show the problem. CodeSandbox installs with a hoisted node_modules, which is exactly the layout that hides this bug. It only appears under a strict linker: Bun isolated, pnpm, or Yarn PnP.
The local reproduction is four files:
// package.json
{
"devDependencies": {
"motion": "13.1.1",
"react": "^19",
"react-dom": "^19",
"@types/react": "^19",
"typescript": "^5"
}
}# bunfig.toml
[install]
linker = "isolated"// tsconfig.json
{ "compilerOptions": { "jsx": "react-jsx", "strict": true, "noEmit": true, "moduleResolution": "bundler", "module": "esnext" } }// a.tsx
import { motion } from "motion/react"
export const A = () => <motion.div className="x" />4. Steps to reproduce
bun installnpx tsc -p .
5. Expected behavior
Types resolve and the file compiles.
7. Environment details
macOS 26.5, Bun 1.4.0, React 19.2, TypeScript 5.9. Also reproduces with pnpm.
Why it happens
A strict linker symlinks each package into a store. Node and TypeScript resolve a symlink to its real path before walking parent directories, so a package sees only what it declares. react is declared and resolves; @types/react is not, so it does not.
skipLibCheck suppresses the errors inside motion's own .d.ts files, but not the broken types they hand to consumers.
Suggested fix
Add @types/react alongside the existing optional peers in packages/motion and packages/framer-motion:
"peerDependencies": {
"@types/react": "*"
},
"peerDependenciesMeta": {
"@types/react": { "optional": true }
}Same pattern @radix-ui/* and [email protected] already ship. Happy to open the PR.
Source: motiondivision/motion