120k

Changelog

RSS

Latest updates and announcements.

2026年7月 - 默认使用 Base UI

从今天开始,Base UI 是 shadcn/ui 的默认组件库

先说一点历史。shadcn/ui 于 2023 年 1 月发布时,基于 Radix 构建。当时,没有其他方案能与之媲美。无样式的 headless 组件、出色的 API、优秀的可访问性,经过数百万应用的实战检验。

几年过去了,构建 Radix 的那些人正在做一些新的东西:Base UI。他们已经成功做过一次了。现在,他们可以把第一次学到的一切带着再做一次。

去年,Base UI 发布了 beta 版,很多人问我们是否会用它替换 Radix。我说过:“对你的生产应用来说,最糟糕的事情就是切换组件库。”我当时是认真的,而且现在依然如此。所以我们没有切换,而是做了 shadcn 风格的事情:我们为 Base UI 重建了每个组件,保持相同的抽象层,并让你自己选择。12 月推出了同时包含两个库的 npx shadcn create。1 月则带来了完整的 Base UI 文档。

然后我们观察了你用它做了什么。

为什么是现在

  • Base UI 已经稳定。 目前版本为 1.6.0,每周下载量超过 600 万。
  • 它还在不断变得更好。 团队会定期发布新的实用组件。
  • 我们自己也在用。 我们启动的每一个新项目都运行在 Base UI 上。
  • 你也在用。 现在通过 shadcn/create 创建的项目,选择 Base UI 的比例已经以 2:1 超过了 Radix。

社区已经做出了选择。我们现在正式确认这一点。

有哪些变化

  • 新项目默认使用 Base UI。 运行 npx shadcn init,Base UI 将作为默认选项。
  • shadcn/create 会优先显示 Base UI。
  • 文档默认使用 Base UI。 组件页面会默认打开 Base UI 选项卡。Radix 文档只需点击一下即可查看。

这对你意味着什么

Radix 并未被弃用。 我们仍然支持它,且每次更新和新组件都会同时为这两个库提供(除非某个组件只存在于 Base UI 中)。

你不需要迁移。 Radix 是一个成熟、经过测试的库。我们今天仍在生产环境中使用它,而且我们不会迁移。如果你的应用运行正常,就继续发布吧。

新项目更想用 Radix? 只需一个标志:

pnpm dlx shadcn init -b radix

如果你有脚本或 CI 在非交互式运行 shadcn init,并且期望使用 Radix,请添加 -b radix 以保持它们走同一路径。

在构建 registry? 如果你想固定到某个特定库,请提供一个 registry:base 配置。现在没有该配置的条目会默认初始化为 Base UI。

准备开始新项目? 我们推荐 Base UI。

当你准备好迁移时

你不需要迁移。但如果你想,我们为此构建了一个 skill:

pnpm dlx skills add shadcn/ui

然后让你的编码代理执行:

migrate accordion to base-ui

它默认采用渐进式迁移:一次迁移一个组件及其使用方式,同时让你的项目保持绿色可构建、可交付。工作过程中两个库会并存。你可以中途停止、发布,然后下周回来时,它会从上次停下的地方继续。或者也可以一次性让它处理整个项目。

为什么用 skill,而不是 codemod?

因为代码是你自己的。你加过变体、改过类名、传过新的 props。codemod 只能处理那些你从没碰过的组件,却会把你改过的地方弄坏。

所以我们改为提供知识:每一次重命名、每一次 props 变化、每一种行为差异,都经过两个库的人工核对。你的代理会读取这些信息,弄清楚 改了什么,并把这些改动一并迁移过去。

机械性的改动会在所有地方修复(asChild 现在是 render)。行为变化会被标记出来,而不会被悄悄修补。由你来决定。

一次迁移会产出什么

每次运行都会留下三样东西:

  • 可工作的代码。 在报告成功之前,已经通过类型检查并完成构建。
  • 每个组件一份报告,位于你项目根目录下的 .migration/:改了什么、哪些没动,以及一份需要手动验证的简短清单。
  • 干净的 git 历史。 每个组件一个 commit,放在一个分支上。回滚就是删除这个分支。

下面是报告的样子:

.migration/accordion.md
# accordion
 
<!-- 日期、使用的策略,以及一句话结论 -->
 
## Changed
 
<!-- 所有被修改的文件,以及改动内容和原因 -->
 
## Left alone
 
<!-- 看起来相关但故意没有触碰的文件 -->
 
## Behavior changes
 
<!-- 能编译通过但行为不同的差异。会被标记,而不会被修补。 -->
 
## Verify by hand
 
<!-- 一个简短的检查清单:打开、点击、用 Tab 浏览。只需一分钟 -->

没有隐藏状态。进度保存在你的文件和 git 历史中,所以任何代理、任何会话、任何一天都能从上次停止的地方继续。

它可与 Claude Code、Cursor,或任何支持 skills 的代理配合使用。我们在真实项目上测试过:60+ 个组件,其中 36 个基于 Radix。一次完整迁移大约用了 25 分钟,每个组件大约 10k tokens。构建干净,定制内容完好保留。

2026年6月 - 聊天界面组件

New Chat
How can I help you today?
Morning, shadcn!
What are we working on today? Press send to start a new conversation
I'm building a chat for our app and the scroll behavior is driving me nuts. Every time the AI streams a reply, the whole thread jumps around.
Demo is read only. Press send to send messages.
"use client"

import { useChat } from "@ai-sdk/react"

今天,我们发布了一组用于构建聊天界面的新组件: MessageScroller, Message, Bubble, Attachment, and Marker

这是聊天组件工作的第一阶段。我们正在一步一步来,重新构想每个部分背后的抽象,并将它们作为你可以复制、组合并适配到产品中的 shadcn/ui 组件发布出来。

我们从对话层开始:滚动、消息行、气泡、附件和标记。

我们问自己:是什么造就了出色的流式聊天体验?然后我们将核心规则抽象为一组基础原语:MessageScroller

pnpm dlx shadcn@latest add message-scroller message bubble attachment marker

MessageScroller

MessageScroller 是对话的滚动容器。它处理那些容易出错的部分:锚定轮次、流式回复、已保存线程恢复、前置历史、跳转到消息、滚动控制以及可见性跟踪。

MessageScroller 负责这些行为,但不负责你的消息、AI 状态、传输层、持久化或模型状态。你只需要提供内容渲染器。

MessageScroller 也可以作为一个无样式的 headless 组件在 @shadcn/react 中使用。

消息、气泡、附件和标记

其余组件涵盖了围绕滚动区域你在日常中所需要的各个部分。

  • Message 用头像、对齐方式、标题、内容、页脚以及分组消息来布局对话中的一行。
  • Bubble 渲染消息表面,支持多种变体、对齐方式、反应、链接、按钮以及可折叠内容。
  • Attachment 渲染文件和图片,包含媒体、元数据、上传状态、操作,以及一个保持操作区域可单独点击的整卡触发器。
  • Marker 渲染状态更新、系统备注、带边框的行,以及带标签的分隔符,例如流式状态、工具活动和日期分隔。

它们刻意保持小巧。将它们组合起来,可用于 AI 聊天、支持收件箱、团队线程、群聊以及特定产品的对话。

scroll-fade 和 shimmer

我们还为这些细节添加了两个新的 CSS 工具类,让聊天界面感觉更好。

scroll-fade 会为滚动容器添加与滚动状态相关的边缘淡出效果。可将其用于 MessageScrollerScrollArea、附件列表行,以及任何你希望在不添加遮罩或滚动监听器的情况下暗示还有更多内容的长列表。

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12
export function ScrollFadeDemo() {
  return (
    <div className="mx-auto w-full max-w-xs overflow-hidden rounded-2xl border">

shimmer 会为实时状态添加文本闪烁效果。可用于诸如“Thinking…”,“Generating response…”,运行中的工具,以及流式标记等场景。

Generating response…

export function ShimmerDemo() {
  return (
    <p className="shimmer text-sm text-muted-foreground">

这两个工具类都包含在 shadcn/tailwind.css 中,因此使用 npx shadcn@latest init 初始化的项目已经自带它们。

@shadcn/react

我们还创建了 @shadcn/react,一个用于无样式、headless React 组件的新包。

第一个原语是 @shadcn/react/message-scroller。注册表组件 用 shadcn/ui 样式对其进行了封装,但滚动行为位于该包中: 锚定、自动跟随、前置保留、滚动命令和可见性。

这让我们能够发布行为,而不会将其绑定到某种视觉样式。你仍然可以获得 与你的项目相匹配的复制粘贴式组件,而复杂的交互逻辑则会在一个地方保持测试。

现已适用于 Radix 和 Base UI。

AI 元素

这不会取代 AI Elements。你 可以继续使用 AI Elements 来实现 AI 界面组件和模式。这个 版本的重点是将聊天的核心部分逐个组件引入 shadcn/ui。

如果你已经在使用 AI Elements 中的某个组件,就不需要 重写你的应用。保留有效的部分。在你想要 更现代的抽象、更新的样式,或在 Radix 和 Base UI 之间获得支持时,再尝试 shadcn/ui 版本。

我们的目标是让这些部分能够轻松独立采用。替换其中一部分, 与现有内容组合起来,然后继续构建。

查看组件

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