motiondivision / motiondivision/motion

[BUG] @types/react is not declared as a peer dependency, breaking types under strict linkers

Open Beginner friendly
#3,801 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
33.7k
Forks
1.4k
Avg merge
1d 10h
Merged PRs (30d)
14

Description

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' property

3. 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

  1. bun install
  2. npx 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 posthog-js@1.422.5 already ship. Happy to open the PR.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Inspect the package manifests in packages/motion and packages/framer-motion, starting with their existing react and react-dom peer dependency declarations. Run the four-file reproduction with bun install and npx tsc -p . under an isolated linker. Done means the optional @types/react peer dependency is declared consistently and the strict TypeScript reproduction compiles.

Written by the indexing model from the issue text.

Assessment

Tech stack
bun, react, typescript
Domain
developer-experience, tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
82/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.