Skip to content

shadcn.io is an independent project built on shadcn/ui

Remix

Remix v2 is now React Router 7. Start new apps there, upgrade a Remix app first, or set up Tailwind CSS v4 and init in a Remix app you keep.

Remix v2's framework lives on as React Router 7: the same routes, loaders and actions, with the packages renamed to react-router and @react-router/*. New apps start on React Router 7, so this guide is for the Remix app you already have.

Upgrade, then install

The path we recommend: move the app to React Router 7, then install like any React Router app.

Upgrade to React Router 7

React Router's guide, Upgrading from Remix (opens in a new tab), takes you through it: turn on Remix v2's future flags one at a time, then swap the @remix-run/* packages for react-router and @react-router/* and add app/routes.ts and react-router.config.ts. Routes, loaders and actions keep working.

The upgrade also brings React 19, which these components are written for: they take ref as a regular prop.

Check Tailwind CSS

Remix's templates set up Tailwind CSS v3. The components need v4: run Tailwind's upgrade tool from the project's root, then check that app/tailwind.css starts with @import "tailwindcss";.

bunx --bun @tailwindcss/upgrade

Run init

shadcn CLILocked
Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

The CLI detects React Router from react-router.config.ts and keeps your ~/* alias, so components go to app/components/ui.

Add a component

shadcn CLILocked
Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
app/routes/_index.tsx
import { Button } from "~/components/ui/button";

export default function Index() {
  return <Button>Click me</Button>;
}

Keep Remix v2

If you can't upgrade yet, the components install in a Remix v2 app on Vite. Check two things first.

Move Tailwind CSS to v4

Run npx @tailwindcss/upgrade, or by hand: install tailwindcss and @tailwindcss/vite, add tailwindcss() to plugins in vite.config.ts next to remix(), delete tailwind.config.ts and the PostCSS config, and replace the three @tailwind lines in app/tailwind.css with @import "tailwindcss";.

Check React

npm ls react

Remix v2 was built for React 18. On React 18 the components work, but a ref you pass to one doesn't reach its element, because they take ref as a prop the way React 19 does.

Run init and add components

shadcn CLILocked
Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

The CLI detects Remix from its @remix-run/* packages and reads the ~/* alias from tsconfig.json. Then add components as above and import them from ~/components/ui/….

FAQ

Is Remix still maintained for React apps?

Remix v2's framework continues as React Router 7, which gets the new features and fixes, so that's where a React app goes next. React Router's docs treat the move as an upgrade ("Upgrading from Remix"): your routes, loaders and actions carry over.

Which command creates a new app with these components?

npx shadcn@latest init https://www.shadcn.io/r/style.json -t react-router. It creates a React Router 7 app with Tailwind CSS v4 and our preset. See the React Router guide.

Why are imports ~/components/ui instead of @/components/ui?

Remix and React Router templates name their alias ~/*, pointing at app/. The CLI reads it from tsconfig.json and writes components with it.

Can I keep Tailwind CSS v3 in my Remix app?

Not for these components. They and the theme use v4's CSS-first setup (@theme, @custom-variant). Tailwind's npx @tailwindcss/upgrade moves most projects over in one run.

Do the components work on React 18?

Mostly, but a ref you pass to a component doesn't reach its element: they're written for React 19, where ref is a regular prop. Upgrading to React Router 7 gets you React 19.

My Remix app uses the classic compiler, not Vite. Can I install?

Move it to Vite first: React Router 7 runs on Vite, so the upgrade needs it anyway, and Tailwind CSS v4's Vite plugin is then one line in vite.config.ts. Remix's docs have a guide for the switch.

How do I use these components in a Remix form?

Put Field, Input and Button inside <Form method="post">. They're regular form controls: give each a name and read them in the action with request.formData(). The Form guide shows validation and errors.

How does init know my app is Remix or React Router?

It looks at the project: a react-router.config.ts file means React Router, @remix-run/* packages mean Remix. Either way it writes components.json, the theme and cn, and keeps your alias.