# Migrate from shadcn Bring an existing shadcn project into Frontfriend while preserving your component styling # 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 ```js module.exports = { 'ff-id': 'your-frontfriend-id-here', aliases: { ui: '@/components/ui', }, }; ``` ## 1. Install Frontfriend For the default Tailwind CSS v4 setup: ```bash npm install @frontfriend/tailwind@next tw-animate-css ``` Or with pnpm: ```bash pnpm add @frontfriend/tailwind@next tw-animate-css ``` ## 2. Run the migration From your project root: ```bash 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: ```bash 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: ```bash npx frontfriend init --force ``` ## 4. Import the Frontfriend theme For Tailwind CSS v4, keep these imports in your app CSS: ```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: ```bash npx frontfriend download button -f react --registry v4 ``` For legacy Tailwind CSS v3 projects, use the legacy registry: ```bash 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 ```bash npx frontfriend migrate --component button ``` ### Migrate from a specific file ```bash 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: ```bash npx frontfriend migrate --keep-shadcn-classes ``` ### Only write local output If you do not want to push the migrated config to Frontfriend cloud: ```bash npx frontfriend migrate --no-push ``` ### Write to a custom output path ```bash 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: ```txt 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: ```bash npx frontfriend migrate npx frontfriend init ``` Or skip migration intentionally: ```bash 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: ```bash 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: ```bash npx frontfriend init --force ```