Meet Frontfriend v4.Your brand. Your rules. Your agents, connected.Explore what’s new
DocumentationMigrate from shadcn
Archived documentation

Migrate from shadcn

Bring an existing shadcn project into Frontfriend while preserving your component styling

This documentation describes an earlier Frontfriend version. Commands and APIs may differ from v4. Read the current v4 documentation →
Read as Markdown

Migrate from shadcn

Use this guide when you already have a shadcn project and want Frontfriend to take over design-system syncing without losing the look of your existing components.

The migration reads your current shadcn components, extracts their styling, rewrites shadcn theme classes to Frontfriend tokens by default, and stores the result as Frontfriend component config.

What gets migrated

Frontfriend scans your components/ui or src/components/ui directory and migrates:

  • cva(...) component variants
  • literal className slots
  • supported shadcn theme classes, mapped to Frontfriend token classes
  • custom CSS from your app theme file, when present
  • the icon library from components.json, when supported

Skipped components are reported in the CLI output so you can review them manually.

Prerequisites

  • Existing shadcn project with components.json
  • Frontfriend installed
  • frontfriend.config.js in the project root
  • Optional but recommended: an ff-id so migrated config can be pushed to your Frontfriend design system
module.exports = {
  'ff-id': 'your-frontfriend-id-here',
  aliases: {
    ui: '@/components/ui',
  },
};

1. Install Frontfriend

For the default Tailwind CSS v4 setup:

npm install @frontfriend/tailwind@next tw-animate-css

Or with pnpm:

pnpm add @frontfriend/tailwind@next tw-animate-css

2. Run the migration

From your project root:

npx frontfriend migrate

By default this scans all components and prepares their styling for Frontfriend. If ff-id is configured, it also pushes the migrated component config to your Frontfriend design system.

3. Initialize Frontfriend

After migration, fetch your design-system tokens:

npx frontfriend init

Frontfriend intentionally blocks init in shadcn projects that have not been migrated yet, so your existing component styling is not overwritten accidentally. If you intentionally want to skip migration and use the design system styling as-is, run:

npx frontfriend init --force

4. Import the Frontfriend theme

For Tailwind CSS v4, keep these imports in your app CSS:

@import "tailwindcss";
@import "@frontfriend/tailwind/theme.css";

The generated Frontfriend theme exposes readable utilities like bg-brand-mid, text-onbrand-strong, and border-neutral-subtle.

5. Replace or add components gradually

Once migration and init are complete, install Frontfriend components into your project:

npx frontfriend download button -f react --registry v4

For legacy Tailwind CSS v3 projects, use the legacy registry:

npx frontfriend download button -f react --registry legacy

You can migrate first, then replace components incrementally instead of doing a full rewrite.

Useful migration options

Migrate one component

npx frontfriend migrate --component button

Migrate from a specific file

npx frontfriend migrate --input ./components/ui/button.tsx

Keep raw shadcn classes

By default, Frontfriend rewrites supported shadcn classes to Frontfriend token classes. To keep the original classes:

npx frontfriend migrate --keep-shadcn-classes

Only write local output

If you do not want to push the migrated config to Frontfriend cloud:

npx frontfriend migrate --no-push

Write to a custom output path

npx frontfriend migrate --output ./frontfriend-migrated-components.json

Custom CSS handling

When migration finds custom CSS in your app theme file, it lifts that CSS into Frontfriend so it can be shared and versioned with the design system.

After a successful cloud push, Frontfriend keeps a local backup next to the original CSS file:

globals.css.bak

Then it leaves only the Tailwind and Frontfriend scaffolding imports in the app CSS.

Troubleshooting

init says the shadcn project has not been migrated

Run:

npx frontfriend migrate
npx frontfriend init

Or skip migration intentionally:

npx frontfriend init --force

A component was skipped

The CLI skips components it cannot safely extract. Run a focused migration to inspect a single component:

npx frontfriend migrate --component button

If needed, keep the component as-is and migrate it manually later.

Migrated styling looks too close to shadcn

That is expected for the first migration: Frontfriend preserves your current look. After migration, update your Frontfriend design system tokens and rerun:

npx frontfriend init --force