React 19 and Next.js 15
Purpose and Scope
This page explains how shadcn/ui approaches React 19 and Next.js 15 compatibility, especially for teams who see peer dependency warnings while installing components. The important distinction is between application compatibility and package-manager resolution. The shadcn/ui documentation states that shadcn/ui is compatible with React 19 and Next.js 15, and the root React 19 guide also notes that the latest release added full React 19 and Tailwind v4 support. The remaining operational problem is usually that a third-party package in the component dependency graph has not yet widened its peer dependency range to include React 19.
Sources: apps/v4/content/docs/(root)/react-19.mdx, apps/v4/content/docs/changelog/2024-10-react-19.mdx
The guide is framed around Next.js 15 because React 19 was tested and supported in that Next.js release. In practical terms, a Next.js 15 project can use the normal shadcn/ui installation path, but npm may stop on strict peer dependency resolution when an installed package still declares only React 16, 17, or 18. pnpm, bun, and yarn are treated differently by the docs: they do not require the same flags in the documented flow, while npm users are prompted by the shadcn CLI to choose how to proceed.
Sources: apps/v4/content/docs/(root)/react-19.mdx
Relevant Source Files
apps/v4/content/docs/(root)/react-19.mdx— The main compatibility guide for Next.js 15 and React 19, including the TL;DR, peer dependency explanation, npm error example, package-manager guidance, and CLI prompt behavior.apps/v4/content/docs/changelog/2024-10-react-19.mdx— The changelog entry announcing that shadcn/ui is compatible with React 19 and Next.js 15 and pointing readers back to the upgrade guide.packages/react/package.json— The package metadata for@shadcn/react, showing its React 19-oriented peer dependency contract, exported entry point, and package build/test scripts.
Compatibility Model
React peer dependencies are declarations made by packages to describe which React versions they expect the consuming app to provide. The React 19 guide shows the desired peer dependency expansion as a diff: package maintainers add ^19.0 to both react and react-dom ranges. Until every dependency used by a component has published that update, npm may report an ERESOLVE unable to resolve dependency tree error even when the code path is otherwise expected to work in the app. That makes the warning a dependency metadata issue first, not automatically a runtime incompatibility.
Sources: apps/v4/content/docs/(root)/react-19.mdx
The project’s own October 2024 changelog gives the high-level support signal: shadcn/ui is now compatible with React 19 and Next.js 15. The current @shadcn/react package metadata reinforces that direction for first-party React utilities. It declares react as a peer dependency with the range >=19, marks both react and @types/react as optional peer dependencies, and develops against React 19.2.3 and React DOM 19.2.3. That package-level contract is narrower than the broader component ecosystem, because generated components may also depend on packages maintained outside this repository.
Sources: apps/v4/content/docs/changelog/2024-10-react-19.mdx, packages/react/package.json
The React 19 guide also contains a cautionary update saying the page may be outdated because full support for React 19 and Tailwind v4 has been added in the latest release. Read that as a sequencing note: the guide remains useful for understanding historical npm behavior and dependency-resolution choices, but users should prefer the latest shadcn CLI and latest registry content when starting or upgrading a project. If a warning appears, check the specific dependency’s published peer dependencies rather than assuming shadcn/ui itself is behind.
Sources: apps/v4/content/docs/(root)/react-19.mdx
Package Manager Behavior
For pnpm, bun, and yarn, the documented Next.js 15 flow is simple: follow the Next.js installation guide and no additional flags are needed. Those package managers may still surface warnings depending on the dependency graph, but the React 19 guide does not require a special install flag for them. This matters when documenting team setup, because a project using pnpm can keep the standard shadcn command sequence while an npm-based project may need an explicit policy for how to answer the CLI prompt.
Sources: apps/v4/content/docs/(root)/react-19.mdx
For npm, the guide documents two accepted choices: --force and --legacy-peer-deps. --force tells npm to ignore and override dependency conflicts while installing. --legacy-peer-deps skips strict peer dependency checks and allows installation with unmet peer dependencies. The shadcn CLI integrates this choice into the interactive flow: when npx shadcn@latest init -d detects React 19, it warns that some packages may fail to install due to peer dependency issues and prompts the user to choose one of those flags.
Sources: apps/v4/content/docs/(root)/react-19.mdx
npx shadcn@latest init -d
# If installing a package directly with npm and peer resolution blocks it:
npm i <package> --force
npm i <package> --legacy-peer-deps
# Conservative fallback if a dependency is not yet ready for React 19:
npm i react@18 react-dom@18The conservative option documented by the guide is to use React 18 until the dependency you need has updated its peer dependency declaration. That path reduces package-manager pressure but should be treated as a project-level downgrade, not a component-specific patch. Whichever path you choose, the guide explicitly tells readers to test the app thoroughly for regressions. That testing step is important because peer dependency flags let installation continue; they do not prove that all interactive, accessibility, animation, or form behavior is correct in your application.
Sources: apps/v4/content/docs/(root)/react-19.mdx
CLI Workflow for Next.js 15 Projects
In a new Next.js 15 project, start with the latest shadcn CLI and let it detect the environment. The documented npm prompt appears during init, and the same resolution choice applies when adding components afterward. This means the workflow does not split into a separate React 19 component catalog; instead, the same registry and component-add flow is used, with package-manager flags only when npm refuses to resolve the dependency tree. Component additions therefore remain operationally the same: run the CLI, choose or provide the dependency-resolution behavior, then test the resulting app.
Sources: apps/v4/content/docs/(root)/react-19.mdx
When troubleshooting, inspect the package named in the npm error rather than only the component you tried to add. The guide recommends checking whether a package lists React 19 as a peer dependency with npm info <package> peerDependencies. If the returned peer range does not include React 19, you can decide whether to proceed with a flag, wait for the package to publish updated metadata, or temporarily run React 18. This package-by-package inspection is the most precise way to separate real incompatibility from stale peer dependency declarations.
Sources: apps/v4/content/docs/(root)/react-19.mdx
npm info <package> peerDependenciesAPI and Package Reference
The visible first-party package contract for @shadcn/react is intentionally small. The package is published as an ES module, is marked side-effect free, ships files from dist, and exports ./message-scroller with separate type and JavaScript entry points. Its peer dependency contract lists react as >=19 and @types/react as >=19, with both marked optional in peerDependenciesMeta. Optional peer metadata means the package can be installed in contexts where the peer is supplied by the host application or tooling, while still declaring the React version it is designed to work with.
Sources: packages/react/package.json
| Surface | Source-level value | Reader impact |
|---|---|---|
| Package name | @shadcn/react | First-party React utility package in the repository. |
| Export | ./message-scroller | Public import subpath with generated declaration and JavaScript files in dist. |
| React peer | react: >=19 | The package is aligned with React 19 or newer. |
| Types peer | @types/react: >=19 | Type consumers should use React 19-compatible React types. |
| Dev React versions | react: 19.2.3, react-dom: 19.2.3 | Package development and tests are performed against React 19-era dependencies. |
| Scripts | build, typecheck, test, test:browser | Maintainers validate the package with tsup, TypeScript, Vitest, and browser tests. |
Upgrade and Verification Checklist
Before upgrading an existing app, confirm that you are using the latest shadcn CLI and registry content, then identify whether your package manager is npm or one of pnpm, bun, or yarn. npm users should choose a peer dependency policy intentionally, because the CLI will ask whether to use --force or --legacy-peer-deps when React 19 is detected. Teams should record that choice in their setup instructions so CI, local development, and onboarding all behave consistently.
Sources: apps/v4/content/docs/(root)/react-19.mdx
After installation, verify the dependency graph and run application-level checks. Use npm info <package> peerDependencies for any dependency that triggers an npm resolution error. Exercise the components you added, especially ones that depend on third-party primitives, command palettes, dialogs, drawers, calendars, or other interactive packages. If the app shows regressions that cannot be resolved with dependency updates, temporarily returning to React 18 is the documented fallback. For related work, read the installation guide for your framework, the Tailwind v4 page, and component-specific pages for the exact dependencies installed by each component.
Sources: apps/v4/content/docs/(root)/react-19.mdx, apps/v4/content/docs/changelog/2024-10-react-19.mdx