117k

Changelog

RSS

Latest updates and announcements.

2026年6月 - GitHub 注册表

现在你可以将任何公开的 GitHub 仓库转换为一个注册表。

在仓库根目录添加一个 registry.json 文件,定义你想要分发的项目,用户就可以使用 shadcn CLI 直接从 GitHub 安装它们。

pnpm dlx shadcn@latest add <username>/<repo>/<item>

例如,要从 acme/toolkit 仓库安装 project-conventions 项目:

pnpm dlx shadcn@latest add acme/toolkit/project-conventions

GitHub 注册表是源注册表。你不需要运行 shadcn build、发布生成的项目 JSON 文件或搭建注册表服务器。CLI 会读取根目录下的 registry.json,解析 include 条目,找到请求的项目,并安装该项目声明的文件。

分发任何内容

注册表项目不限于组件。GitHub 注册表可以分发组件、hooks、实用工具、设计 token、功能套件、项目规范、代理指令、测试配置、CI 工作流、发布工作流、模板、codemod、迁移套件以及其他项目文件。

例如,某个仓库可以公开一个 project-conventions 项目,用于安装共享文档、编辑器设置和代理指令:

registry.json
{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "acme-toolkit",
  "homepage": "https://github.com/acme/toolkit",
  "items": [
    {
      "name": "project-conventions",
      "type": "registry:item",
      "files": [
        {
          "path": "AGENTS.md",
          "type": "registry:file",
          "target": "~/AGENTS.md"
        },
        {
          "path": ".editorconfig",
          "type": "registry:file",
          "target": "~/.editorconfig"
        },
        {
          "path": "docs/conventions.md",
          "type": "registry:file",
          "target": "~/docs/conventions.md"
        }
      ]
    }
  ]
}

命令

GitHub 注册表地址与其他注册表地址使用相同的命令。

列出 GitHub 注册表中的项目:

pnpm dlx shadcn@latest list acme/toolkit

搜索项目:

pnpm dlx shadcn@latest search acme/toolkit --query conventions

查看某个项目:

pnpm dlx shadcn@latest view acme/toolkit/project-conventions

安装某个项目:

pnpm dlx shadcn@latest add acme/toolkit/project-conventions

查看 GitHub 注册表 文档以获取完整指南。

2026 年 5 月 - shadcn eject

当我们为 Radix 和 Base UI 都添加支持时,我们需要一个用于共享 Tailwind 工具类的地方,这些工具类是这两个库都依赖的,例如 data-open:data-closed: 这样的自定义变体,以及 no-scrollbar 这样的工具类。

在处理 RTL 支持时,我们还遇到了一些 bug,把它们在一个共享位置修复要比在每个组件中重复修复更容易。

所以我们创建了 shadcn/tailwind.css。当你运行 init 时,它会将 @import "shadcn/tailwind.css" 添加到你的全局 CSS 文件中。它的工作方式与其他 CSS 导入类似,例如 tw-animate-css:这是一个小型依赖,在生产环境中会被 tree-shaken,并在构建时解析。

如果你不希望为了这段 CSS 依赖 shadcn 包,我们新增了 shadcn eject 命令。它会将 shadcn/tailwind.css 内联到你的全局 CSS 文件中,并从你的项目中移除 shadcn 依赖。

pnpm dlx shadcn@latest eject

之前

@import "tailwindcss";
@import "tw-animate-css";
@import "shadcn/tailwind.css";

之后

@import "tailwindcss";
@import "tw-animate-css";
/* 从 shadcn@4.8.3 中导出 */
@theme inline {
  @keyframes accordion-down {
    from {
      height: 0;
    }
    to {
      height: var(
        --radix-accordion-content-height,
        var(--accordion-panel-height, auto)
      );
    }
  }
}
 
@custom-variant data-open {
  &:where([data-state="open"]),
  &:where([data-open]:not([data-open="false"])) {
    @slot;
  }
}

在 monorepo 中,请从包含你的 components.json 和全局 CSS 文件的 workspace 中运行该命令:

pnpm dlx shadcn@latest eject -c packages/ui

更多详情请参阅 CLI 文档

2026年5月 - 介绍 Rhea

介绍 Rhea,一种新的 shadcn/ui 风格。更紧凑的 Luma。更小的间距。更高的密度。专为聚焦型产品界面打造。

Rhea 风格预览在 shadcn/create 中试用 Rhea

Rhea 的起点是一个我们经常听到的简单请求:Luma,但更紧凑一些。我们研究了人们如何使用这些新风格,以及他们想要什么,结果模式非常清晰。很多团队希望保留 Luma 的柔和感和形状,同时拥有更紧凑的间距、更小的控件,以及更高的信息密度。

Rhea 保留了同样圆润的基础,但将其做得更紧凑,适用于那些空间很重要的产品界面。按钮、输入框、菜单、卡片和列表都排得稍微更紧凑一些,这样界面可以承载更多内容,同时不会显得拥挤。

为什么要有一种新风格?

我们曾考虑把这只是作为 Luma 的间距调整,但 --spacing 是一个乘数。改动它会改变整个应用中熟悉的工具类含义。p-2w-4m-16 将不再表示相同的尺寸。

这种取舍让人感觉不对。紧凑不应该迫使你重新学习 Tailwind 的间距刻度,或者怀疑同一个工具类在一种风格里是否和另一种风格含义不同。

所以,Rhea 作为一种新风格出现。它让我们能够直接调整组件尺寸、间距和密度,同时保持底层工具类刻度的可预测性。

现已在 shadcn/create 中提供,适用于 Radix 和 Base UI。

试用 Rhea

2026年5月 - Registry Include 和 Validate

本次发布为 registry 作者带来了两个更新:

  • include 用于通过多个 registry.json 文件组合大型源注册表。
  • shadcn registry validate 用于在发布前检查源注册表。

这使得无需手动维护一个大型 registry.json 文件,也能更轻松地维护源注册表和动态注册表。

Registry 作者现在可以将一个大型源注册表分散到多个 registry.json 文件中进行组织,并通过 shadcn build 将它们组合起来。

registry.json
components
└── ui
    ├── button.tsx
    ├── input.tsx
    └── registry.json
hooks
├── registry.json
├── use-media-query.ts
└── use-toggle.ts
registry.json
{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "acme",
  "homepage": "https://acme.com",
  "include": [
    "components/ui/registry.json",
    "hooks/registry.json"
  ]
}

包含的 registry.json 文件是用于组合的有效注册表文件,并且可以省略 namehomepage。只有根 registry.json 必须定义 注册表元数据。

components/ui/registry.json
{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "items": [
    {
      "name": "button",
      "type": "registry:ui",
      "files": [
        {
          "path": "button.tsx",
          "type": "registry:ui"
        }
      ]
    }
  ]
}

构建输出

shadcn build 会解析包含的注册表,并写出一个扁平化的 registry.json,且不包含 include。项目文件路径会从根 注册表中保留,因此在 components/ui/registry.json 中声明的文件会在构建后的注册表项中写为 components/ui/button.tsx

验证你的注册表

现在你可以在发布或提供服务之前验证源注册表。

pnpm dlx shadcn registry validate

验证会直接针对源注册表文件运行。你不需要先 运行 shadcn build

该命令会检查根 registry.json、包含的注册表文件、项目 schema 错误、重复的项目名称、include 规则,以及本地项目文件路径。 验证会在一次运行中报告它能找到的所有可操作错误。

注册表加载器

shadcn/registry 包也导出 loadRegistryloadRegistryItem,用于动态注册表路由。

app/r/registry.json/route.ts
import { loadRegistry } from "shadcn/registry"
 
export async function GET() {
  const registry = await loadRegistry()
 
  return Response.json(registry)
}
app/r/[name].json/route.ts
import { loadRegistryItem } from "shadcn/registry"
 
export async function GET(
  _: Request,
  { params }: { params: Promise<{ name: string }> }
) {
  const { name } = await params
  const item = await loadRegistryItem(name)
 
  return Response.json(item)
}

有关更多详情,请参阅 registry.json 文档入门指南

2026年5月 - 包导入和目标别名

我们已在 shadcn@4.7.0files.target 中添加了对包导入和别名的支持。

包导入

shadcn CLI 现在支持用于安装组件、重写导入以及解析第三方注册表的 package.json#imports。你可以直接使用 package.json 中私有的 #... 导入别名,而不必仅依赖 tsconfig.json 中的 compilerOptions.paths

package.json
{
  "imports": {
    "#components/*": "./src/components/*.tsx",
    "#lib/*": "./src/lib/*.ts",
    "#hooks/*": "./src/hooks/*.ts"
  }
}

然后在 components.json 中使用相同的根路径:

components.json
{
  "aliases": {
    "components": "#components",
    "ui": "#components/ui",
    "lib": "#lib",
    "hooks": "#hooks",
    "utils": "#lib/utils"
  }
}

这也适用于 monorepo,其中应用本地文件使用包导入,共享 UI 文件则从工作区包导出中导入。

有关设置详情,请参阅包导入指南

目标别名

注册表项现在可以在 files[].target 中使用目标别名,将文件安装到用户配置的 shadcn 目录下。例如,下面的注册表项会将 prompt-input.tsx 文件安装到 ui/ai 目录下。

example.json
{
  "files": [
    {
      "path": "registry/default/ai/prompt-input.tsx",
      "type": "registry:ui",
      "target": "@ui/ai/prompt-input.tsx"
    }
  ]
}

更多详情请参阅注册表示例