Skip to content

Commit c5d90c7

Browse files
authored
feat: add migrate radix command (#7586)
* feat(shadcn): add migrate-radix command * feat(shadcn): fix and test edge cases * test(shadcn): add tests for all primitives * fix(shadcn): edge cases and add yes option * fix * chore(shadcn): add changeset * style: fix code styles * docs: update changelog * fix: format * feat: update changelog * fix: format
1 parent b1fd13f commit c5d90c7

6 files changed

Lines changed: 1532 additions & 6 deletions

File tree

.changeset/stupid-planes-guess.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"shadcn": patch
3+
---
4+
5+
add migrate-radix

apps/v4/content/docs/(root)/changelog.mdx

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,25 @@ description: Latest updates and announcements.
44
toc: false
55
---
66

7+
## June 2025 - `radix-ui`
8+
9+
We've added a new command to migrate to the new `radix-ui` package. This command will replace all `@radix-ui/react-*` imports with `radix-ui`.
10+
11+
```bash
12+
npx shadcn@latest migrate radix
13+
```
14+
15+
It will automatically update all imports in your `ui` components and install `radix-ui` as a dependency.
16+
17+
```diff showLineNumbers title="components/ui/alert-dialog.tsx"
18+
- import * as AlertDialogPrimitive from "@radix-ui/react-dialog"
19+
+ import { AlertDialog as AlertDialogPrimitive } from "radix-ui"
20+
```
21+
22+
Make sure to test your components and project after running the command.
23+
24+
**Note:** To update imports for newly added components, run the migration command again.
25+
726
## June 2025 - Calendar Component
827

928
We've upgraded the `Calendar` component to the latest version of [React DayPicker](https://daypicker.dev).
@@ -42,9 +61,9 @@ Learn more in the thread here: https://x.com/shadcn/status/1917597228513853603
4261

4362
We tagged shadcn 2.5.0 earlier this week. It comes with a pretty cool feature: **resolve anywhere**.
4463

45-
Registries can now place files anywhere in an app and well properly resolve imports. No need to stick to a fixed file structure. It can even add files outside the registry itself.
64+
Registries can now place files anywhere in an app and we'll properly resolve imports. No need to stick to a fixed file structure. It can even add files outside the registry itself.
4665

47-
On install, we track all files and perform a multi-pass resolution to correctly handle imports and aliases. Its fast.
66+
On install, we track all files and perform a multi-pass resolution to correctly handle imports and aliases. It's fast.
4867

4968
## March 2025 - Cross-framework Route Support
5069

@@ -61,7 +80,7 @@ What's New:
6180
- The CLI can now initialize projects with Tailwind v4.
6281
- Full support for the new @theme directive and @theme inline option.
6382
- All components are updated for Tailwind v4 and React 19.
64-
- Weve removed the forwardRefs and adjusted the types.
83+
- We've removed the forwardRefs and adjusted the types.
6584
- Every primitive now has a data-slot attribute for styling.
6685
- We've fixed and cleaned up the style of the components.
6786
- We're deprecating the toast component in favor of sonner.
@@ -139,7 +158,7 @@ The new CLI is now available. It's a complete rewrite with a lot of new features
139158
This is a major step towards distributing code that you and your LLMs can access and use.
140159

141160
1. First up, the cli now has support for all major React framework out of the box. Next.js, Remix, Vite and Laravel. And when you init into a new app, we update your existing Tailwind files instead of overriding.
142-
2. A component now ship its own dependencies. Take the accordion for example, it can define its Tailwind keyframes. When you add it to your project, well update your tailwind.config.ts file accordingly.
161+
2. A component now ship its own dependencies. Take the accordion for example, it can define its Tailwind keyframes. When you add it to your project, we'll update your tailwind.config.ts file accordingly.
143162
3. You can also install remote components using url. `npx shadcn add https://acme.com/registry/navbar.json`.
144163
4. We have also improve the init command. It does framework detection and can even init a brand new Next.js app in one command. `npx shadcn init`.
145164
5. We have created a new schema that you can use to ship your own component registry. And since it has support for urls, you can even use it to distribute private components.

apps/v4/mdx-components.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export const mdxComponents = {
5252
.replace(/\?/g, "")
5353
.toLowerCase()}
5454
className={cn(
55-
"font-heading mt-12 scroll-m-28 text-2xl font-medium tracking-tight first:mt-0 lg:mt-20 [&+p]:!mt-4",
55+
"font-heading mt-12 scroll-m-28 text-2xl font-medium tracking-tight first:mt-0 lg:mt-20 [&+p]:!mt-4 *:[code]:text-2xl",
5656
className
5757
)}
5858
{...props}
@@ -62,7 +62,7 @@ export const mdxComponents = {
6262
h3: ({ className, ...props }: React.ComponentProps<"h3">) => (
6363
<h3
6464
className={cn(
65-
"font-heading mt-8 scroll-m-28 text-xl font-semibold tracking-tight",
65+
"font-heading mt-8 scroll-m-28 text-xl font-semibold tracking-tight *:[code]:text-xl",
6666
className
6767
)}
6868
{...props}

packages/shadcn/src/commands/migrate.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import path from "path"
22
import { migrateIcons } from "@/src/migrations/migrate-icons"
3+
import { migrateRadix } from "@/src/migrations/migrate-radix"
34
import { preFlightMigrate } from "@/src/preflights/preflight-migrate"
45
import * as ERRORS from "@/src/utils/errors"
56
import { handleError } from "@/src/utils/handle-error"
@@ -12,11 +13,16 @@ export const migrations = [
1213
name: "icons",
1314
description: "migrate your ui components to a different icon library.",
1415
},
16+
{
17+
name: "radix",
18+
description: "migrate to radix-ui.",
19+
},
1520
] as const
1621

1722
export const migrateOptionsSchema = z.object({
1823
cwd: z.string(),
1924
list: z.boolean(),
25+
yes: z.boolean(),
2026
migration: z
2127
.string()
2228
.refine(
@@ -40,12 +46,14 @@ export const migrate = new Command()
4046
process.cwd()
4147
)
4248
.option("-l, --list", "list all migrations.", false)
49+
.option("-y, --yes", "skip confirmation prompt.", false)
4350
.action(async (migration, opts) => {
4451
try {
4552
const options = migrateOptionsSchema.parse({
4653
cwd: path.resolve(opts.cwd),
4754
migration,
4855
list: opts.list,
56+
yes: opts.yes,
4957
})
5058

5159
if (options.list || !options.migration) {
@@ -82,6 +90,10 @@ export const migrate = new Command()
8290
if (options.migration === "icons") {
8391
await migrateIcons(config)
8492
}
93+
94+
if (options.migration === "radix") {
95+
await migrateRadix(config, { yes: options.yes })
96+
}
8597
} catch (error) {
8698
logger.break()
8799
handleError(error)

0 commit comments

Comments
 (0)