Skip to content

shadcn/ui 源码阅读指南

  • 依据 shadcn/ui 仓库: branch main

学习前先克隆项目:

cd external
git clone --depth 1 https://github.com/shadcn-ui/ui.git shadcn-ui

项目概述

shadcn/ui 不是传统的 npm 组件库,而是一个 CLI 工具,它将组件源码直接复制到你的项目中,让你完全拥有和自定义组件代码。

  • GitHub: https://github.com/shadcn-ui/ui
  • 官网: https://ui.shadcn.com
  • 本地路径: external/shadcn-ui
  • 核心依赖: Radix UI (无样式行为基元) + Tailwind CSS (样式)

核心理念

传统的 npm 包                    shadcn/ui
─────────────                    ─────────
npm install @acme/ui             npx shadcn add button
    ↓                               ↓
node_modules 黑盒               components/ui/button.tsx (你的代码)
    ↓                               ↓
import { Button } from ...      import { Button } from "@/components/ui/button"
    ↓                               ↓
无法修改源码                     完全可控,直接改

项目结构

shadcn-ui/
├── packages/
│   ├── shadcn/                      # CLI 工具 (核心)
│   │   └── src/
│   │       ├── index.ts            # CLI 入口
│   │       ├── commands/           # CLI 命令 (init, add, build, diff)
│   │       ├── registry/           # 组件注册表系统
│   │       ├── schema/             # components.json 配置 schema
│   │       ├── utils/              # 工具函数
│   │       ├── mcp/                # MCP 协议支持
│   │       └── migrations/         # 配置迁移
│   └── tests/                      # 测试
├── apps/v4/                        # 文档网站 (Next.js)
│   ├── registry/                   # 组件注册表 (JSON)
│   ├── registry.json               # 默认注册表配置
│   ├── components/                 # 文档站用的组件
│   └── content/                    # MDX 文档
├── templates/                      # 模板项目
│   ├── next-app/ next-monorepo/
│   ├── vite-app/ vite-monorepo/
│   ├── astro-app/ astro-monorepo/
│   └── start-app/ start-monorepo/
└── skills/                         # AI 辅助技能

学习阶段

阶段 1: 体验使用

  1. 初始化一个项目
npx shadcn@latest init
  1. 添加组件
npx shadcn@latest add button
npx shadcn@latest add dialog
  1. 理解生成的文件

  2. components.json — 项目配置 (tailwind config, aliases, registry url)

  3. components/ui/ — 复制的组件源码
  4. lib/utils.tscn() 工具函数 (tailwind-merge + clsx)

阶段 2: 理解 CLI 架构

核心代码: packages/shadcn/src/

  1. CLI 入口

  2. 阅读 packages/shadcn/src/index.ts — 了解 commander 如何注册命令

  3. 工作原理: 用 @commander-js/extra-typings 构建 CLI
  4. TypeScript 编译为 ESM ("type": "module")

  5. 核心命令

文件 命令 用途
commands/init.ts shadcn init 初始化项目配置
commands/add.ts shadcn add 添加组件
commands/build.ts shadcn build 构建 registry
commands/diff.ts shadcn diff 对比组件差异
commands/migrate.ts shadcn migrate 迁移配置
commands/search.ts shadcn search 搜索组件

阶段 3: 理解 Registry 系统

核心代码: packages/shadcn/src/registry/

  1. Registry 是什么

  2. 一个 JSON 配置文件,定义所有可用的组件、依赖、文件列表

  3. 默认 registry: https://ui.shadcn.com/r/styles/default/registry.json
  4. 本地 registry: apps/v4/registry.json

  5. 关键模块

文件 用途
registry/api.ts 从 URL 或本地加载 registry
registry/loader.ts 加载组件文件
registry/resolver.ts 解析组件依赖树
registry/parser.ts 解析 TypeScript/JSX 源码
registry/builder.ts 构建最终输出
registry/schema.ts Zod schema 定义
  1. Registry 工作流程
shadcn add button
加载 registry.json → 解析 button 的定义
递归解析依赖 (button → @radix-ui/react-slot)
从 registry 获取每个文件的源码
转换为目标格式 (TypeScript/JavaScript)
写入 components/ui/button.tsx
安装 npm 依赖 (如 react-aria, class-variance-authority)

阶段 4: 理解组件设计

  1. 组件架构

  2. 基元层: Radix UI / React Aria (无样式、可访问的行为)

  3. 样式层: Tailwind CSS + class-variance-authority (变体)
  4. 组合层: cn() = clsx + tailwind-merge

  5. 阅读示例组件

  6. apps/v4/components/ui/button.tsx — 简单组件

  7. apps/v4/components/ui/dialog.tsx — 复合组件
  8. apps/v4/components/ui/form.tsx — 结合 react-hook-form

阶段 5: 理解模板系统

  1. 模板项目 (templates/)

    • next-app → Next.js App Router
    • vite-app → Vite + React SPA
    • astro-app → Astro
    • start-app → TanStack Start
    • Monorepo 变体: *-monorepo/
  2. 模板如何工作

    • 每个模板定义框架特定的配置
    • shadcn init 使用对应模板初始化项目
    • 模板包含惯例文件: components.json, tailwind.config, lib/utils.ts

阶段 6: 进阶了解

  1. diff 命令实现

    • commands/diff.ts — 对比本地组件和上游 registry 的差异
    • 类似 git diff,帮助你追踪上游更新
  2. build 命令

    • commands/build.ts — 构建自定义 registry
    • 用于部署私有组件库
  3. MCP 协议

    • mcp/ — Model Context Protocol 集成
    • 让 AI 助手通过 MCP 服务器管理 shadcn/ui 组件

关键概念

概念 说明
Registry 组件的 JSON 清单,列出所有可用组件
components.json 项目级配置,记录别名、样式、registry 地址
cn() clsx + tailwind-merge 的组合函数
Class Variance Authority 类型安全的组件变体 API
Radix UI 无样式可访问 UI 基元库
Tailwind CSS 原子化 CSS 框架

技术栈

技术 用途
TypeScript 语言
Commander.js CLI 框架
Zod Schema 验证
tsup TypeScript 构建
Vitest 测试
Next.js 文档网站
Turbo Monorepo 管理
Radix UI / React Aria 组件基元
Tailwind CSS 样式
Backlinks (1)
flowchart LR
  n0["AI"]
  n1["Database"]
  n2["Dev Tools"]
  n3["Emoji"]
  n4["Frontend"]
  n5["Game Dev"]
  n6["Collection"]
  n7["Languages"]
  n8["Maps"]
  n9["Media"]
  n10["Monitor"]
  n11["Plans"]
  n12["对象存储基本用法(Bucket / Object / 常用操作)"]
  n13["对象存储数据迁移(R2 → MinIO / 跨厂商搬迁)"]
  n14["Object Storage"]
  n15["挂载 Bucket 为本地文件系统(FUSE Mount)"]
  n16["对象存储签名 URL(Signed URL)原理与实战"]
  n17["对象存储供应商对比(S3 / R2 / OSS / Supabase / MinIO)"]
  n18["Prototypes"]
  n19["Research"]
  n20["Better Auth 源码阅读指南"]
  n21["DuckDB 环境与基本使用"]
  n22["DuckDB 实战研究"]
  n23["DuckDB 模拟数据"]
  n24["PostgreSQL 数据用 DuckDB 加速查询"]
  n25["HK 角色阅读"]
  n26["HK 台词阅读"]
  n27["Hollow Knight 英语主题"]
  n28["HK 物品阅读"]
  n29["HK 地点阅读"]
  n30["HK 世界观 / Lore 阅读"]
  n31["HK 英语学习素材清单"]
  n32["英语学习 Dashboard"]
  n33["English Scraps Archive"]
  n34["English Scraps 使用指南"]
  n35["Jellyfin 源码阅读指南"]
  n36["Lux 资料整理"]
  n37["Nest Commander 学习资料"]
  n38["NestJS 源码阅读指南"]
  n39["Protomaps 自建底图研究"]
  n40["自制 PMTiles 地图(最简单例子)"]
  n41["MapLibre 集成 Protomaps"]
  n42["PMTiles 格式与工具链"]
  n43["上海地区底图项目"]
  n44["Redash 源码阅读指南"]
  n45["Rust 学习计划"]
  n46["shadcn/ui 源码阅读指南"]
  n47["TRIP 项目核心原理与代码阅读指南"]
  n1 --> n22
  n6 --> n0
  n6 --> n1
  n6 --> n2
  n6 --> n3
  n6 --> n4
  n6 --> n5
  n6 --> n7
  n6 --> n8
  n6 --> n9
  n6 --> n10
  n6 --> n11
  n6 --> n19
  n12 --> n13
  n12 --> n16
  n12 --> n17
  n12 --> n18
  n13 --> n12
  n13 --> n15
  n13 --> n16
  n13 --> n17
  n14 --> n12
  n14 --> n13
  n14 --> n15
  n14 --> n16
  n14 --> n17
  n15 --> n12
  n15 --> n16
  n15 --> n17
  n16 --> n18
  n17 --> n12
  n17 --> n13
  n17 --> n16
  n17 --> n18
  n18 --> n12
  n18 --> n15
  n18 --> n16
  n18 --> n17
  n18 --> n39
  n19 --> n20
  n19 --> n22
  n19 --> n32
  n19 --> n35
  n19 --> n36
  n19 --> n37
  n19 --> n38
  n19 --> n39
  n19 --> n44
  n19 --> n45
  n19 --> n46
  n19 --> n47
  n21 --> n23
  n22 --> n1
  n22 --> n19
  n22 --> n21
  n22 --> n23
  n22 --> n24
  n23 --> n21
  n23 --> n24
  n24 --> n22
  n24 --> n23
  n27 --> n25
  n27 --> n26
  n27 --> n28
  n27 --> n29
  n27 --> n30
  n27 --> n31
  n27 --> n34
  n31 --> n26
  n32 --> n27
  n32 --> n33
  n32 --> n34
  n34 --> n32
  n34 --> n33
  n39 --> n8
  n39 --> n40
  n39 --> n41
  n39 --> n42
  n39 --> n43
  n40 --> n42
  n41 --> n18
  n41 --> n43
  n42 --> n40
  n42 --> n43
  n43 --> n41
  n43 --> n42
  click n0 "../../../collection/ai/" "AI"
  click n1 "../../../collection/database/" "Database"
  click n2 "../../../collection/dev-tools/" "Dev Tools"
  click n3 "../../../collection/emoji/" "Emoji"
  click n4 "../../../collection/frontend/" "Frontend"
  click n5 "../../../collection/game-dev/" "Game Dev"
  click n6 "../../../collection/" "Collection"
  click n7 "../../../collection/languages/" "Languages"
  click n8 "../../../collection/maps/" "Maps"
  click n9 "../../../collection/media/" "Media"
  click n10 "../../../collection/monitor/" "Monitor"
  click n11 "../../../collection/scraps/plans/" "Plans"
  click n12 "../../../knowledge/infrastructure/cloud/object-storage/basic-usage/" "对象存储基本用法(Bucket / Object / 常用操作)"
  click n13 "../../../knowledge/infrastructure/cloud/object-storage/data-migration/" "对象存储数据迁移(R2 → MinIO / 跨厂商搬迁)"
  click n14 "../../../knowledge/infrastructure/cloud/object-storage/" "Object Storage"
  click n15 "../../../knowledge/infrastructure/cloud/object-storage/mount-bucket/" "挂载 Bucket 为本地文件系统(FUSE Mount)"
  click n16 "../../../knowledge/infrastructure/cloud/object-storage/signed-url/" "对象存储签名 URL(Signed URL)原理与实战"
  click n17 "../../../knowledge/infrastructure/cloud/object-storage/vendors-comparison/" "对象存储供应商对比(S3 / R2 / OSS / Supabase / MinIO)"
  click n18 "../../../prototypes/" "Prototypes"
  click n19 "../../" "Research"
  click n20 "../better-auth/" "Better Auth 源码阅读指南"
  click n21 "../duckdb/basic-usage/" "DuckDB 环境与基本使用"
  click n22 "../duckdb/" "DuckDB 实战研究"
  click n23 "../duckdb/mock-data/" "DuckDB 模拟数据"
  click n24 "../duckdb/postgresql-acceleration/" "PostgreSQL 数据用 DuckDB 加速查询"
  click n25 "../english/hollow-knight/characters/" "HK 角色阅读"
  click n26 "../english/hollow-knight/dialogues/" "HK 台词阅读"
  click n27 "../english/hollow-knight/" "Hollow Knight 英语主题"
  click n28 "../english/hollow-knight/items/" "HK 物品阅读"
  click n29 "../english/hollow-knight/locations/" "HK 地点阅读"
  click n30 "../english/hollow-knight/lore/" "HK 世界观 / Lore 阅读"
  click n31 "../english/hollow-knight/resources/" "HK 英语学习素材清单"
  click n32 "../english/" "英语学习 Dashboard"
  click n33 "../english/scraps/archive/" "English Scraps Archive"
  click n34 "../english/scraps/" "English Scraps 使用指南"
  click n35 "../jellyfin/" "Jellyfin 源码阅读指南"
  click n36 "../lux/" "Lux 资料整理"
  click n37 "../nest-commander/" "Nest Commander 学习资料"
  click n38 "../nestjs/" "NestJS 源码阅读指南"
  click n39 "../protomaps/" "Protomaps 自建底图研究"
  click n40 "../protomaps/make-own-map/" "自制 PMTiles 地图(最简单例子)"
  click n41 "../protomaps/maplibre/" "MapLibre 集成 Protomaps"
  click n42 "../protomaps/pmtiles/" "PMTiles 格式与工具链"
  click n43 "../protomaps/shanghai-map/" "上海地区底图项目"
  click n44 "../redash/" "Redash 源码阅读指南"
  click n45 "../rust/" "Rust 学习计划"
  click n46 "./" "shadcn/ui 源码阅读指南"
  click n47 "../trip/" "TRIP 项目核心原理与代码阅读指南"