- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Avatar
- Badge
- Breadcrumb
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Collapsible
- Combobox
- Command
- Context Menu
- Data Table
- Date Picker
- Dialog
- Direction
- Drawer
- Dropdown Menu
- Empty
- Field
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kbd
- Label
- Menubar
- Native Select
- Navigation Menu
- Pagination
- Popover
- Progress
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Toggle Group
- Tooltip
- Typography
命名空间注册表允许你在一个项目中配置多个资源来源。这意味着你可以从不同的注册表安装组件、库、工具、AI 提示、配置文件和其他资源,无论它们是公开的、第三方的,还是你自己定制的私有库。
目录
概览
注册表命名空间以 @ 开头,用于组织和引用来自不同来源的资源。资源可以是任何类型的内容:组件、库、工具、hooks、AI 提示、配置文件、主题等。例如:
@shadcn/button- 来自 shadcn 注册表的 UI 组件@v0/dashboard- 来自 v0 注册表的仪表盘组件@ai-elements/input- 来自 AI elements 注册表的 AI 提示输入@acme/auth-utils- 来自你们公司私有注册表的认证工具@ai/chatbot-rules- 来自 AI 资源注册表的 AI 提示规则@themes/dark-mode- 来自主题注册表的主题配置
去中心化命名空间系统
我们刻意将命名空间系统设计为去中心化。对于开源命名空间,有一个中心化的开源注册表索引,但你完全可以创建并使用任何你想要的命名空间。
这种去中心化的方式让你可以根据组织的实际需求,完全自由地组织资源。
你可以为不同用途创建多个注册表:
{
"registries": {
"@acme-ui": "https://registry.acme.com/ui/{name}.json",
"@acme-docs": "https://registry.acme.com/docs/{name}.json",
"@acme-ai": "https://registry.acme.com/ai/{name}.json",
"@acme-themes": "https://registry.acme.com/themes/{name}.json",
"@acme-internal": {
"url": "https://internal.acme.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${INTERNAL_TOKEN}"
}
}
}
}这让你可以:
- 按类型组织:将 UI 组件、文档、AI 资源等分开管理
- 按团队组织:不同团队可以维护自己的注册表
- 按可见性组织:公开资源与私有资源分开
- 按版本组织:稳定版与实验版注册表分离
- 避免命名冲突:由于没有中心化权威,你不需要担心命名空间冲突
多注册表配置示例
按资源类型
{
"@components": "https://cdn.company.com/components/{name}.json",
"@hooks": "https://cdn.company.com/hooks/{name}.json",
"@utils": "https://cdn.company.com/utils/{name}.json",
"@prompts": "https://cdn.company.com/ai-prompts/{name}.json"
}按团队或部门
{
"@design": "https://create.company.com/registry/{name}.json",
"@engineering": "https://eng.company.com/registry/{name}.json",
"@marketing": "https://marketing.company.com/registry/{name}.json"
}按稳定性
{
"@stable": "https://registry.company.com/stable/{name}.json",
"@latest": "https://registry.company.com/beta/{name}.json",
"@experimental": "https://registry.company.com/experimental/{name}.json"
}快速开始
安装资源
配置完成后,你可以使用命名空间语法安装资源:
pnpm dlx shadcn@latest add @v0/dashboard
或者一次安装多个资源:
pnpm dlx shadcn@latest add @acme/header @lib/auth-utils @ai/chatbot-rules
快速配置
将注册表添加到你的 components.json:
{
"registries": {
"@v0": "https://v0.dev/chat/b/{name}",
"@acme": "https://registry.acme.com/resources/{name}.json"
}
}然后开始安装:
pnpm dlx shadcn@latest add @acme/button
注册表命名规范
注册表名称必须遵循以下规则:
- 以
@符号开头 - 仅包含字母数字字符、连字符和下划线
- 有效名称示例:
@v0、@acme-ui、@my_company
资源的引用格式是:@namespace/resource-name
配置
命名空间注册表在 components.json 文件的 registries 字段中配置。
基础配置
配置注册表最简单的方式是使用 URL 模板字符串:
{
"registries": {
"@v0": "https://v0.dev/chat/b/{name}",
"@acme": "https://registry.acme.com/resources/{name}.json",
"@lib": "https://lib.company.com/utilities/{name}",
"@ai": "https://ai-resources.com/r/{name}.json"
}
}注意: 当你运行
npx shadcn@latest add @namespace/resource-name时,URL 中的{name}占位符会自动解析并替换为资源名称。例如,@acme/button会变成https://registry.acme.com/resources/button.json。更多细节请参见 URL 模式系统。
高级配置
对于需要认证或额外参数的注册表,请使用对象格式:
{
"registries": {
"@private": {
"url": "https://api.company.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}",
"X-API-Key": "${API_KEY}"
},
"params": {
"version": "latest",
"format": "json"
}
}
}
}注意:
${VAR_NAME}形式的环境变量会自动从你的环境变量(process.env)中展开。这适用于 URL、headers 和 params。例如,${REGISTRY_TOKEN}会被替换为process.env.REGISTRY_TOKEN的值。有关如何使用环境变量的更多信息,请参见 认证与安全。
URL 模式系统
注册表 URL 支持以下占位符:
{name} 占位符(必需)
{name} 占位符会被资源名称替换:
{
"@acme": "https://registry.acme.com/{name}.json"
}安装 @acme/button 时,URL 会变成:https://registry.acme.com/button.json
安装 @acme/auth-utils 时,URL 会变成:https://registry.acme.com/auth-utils.json
{style} 占位符(可选)
{style} 占位符会被当前样式配置替换:
{
"@themes": "https://registry.example.com/{style}/{name}.json"
}当样式设置为 new-york 时,安装 @themes/card 会解析为:https://registry.example.com/new-york/card.json
style 占位符是可选的。当你希望同一个资源提供不同版本时,可以使用它。例如,你可以针对每种样式提供不同版本的组件。
认证与安全
环境变量
使用环境变量安全地存储凭据:
{
"registries": {
"@private": {
"url": "https://api.company.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}然后设置环境变量:
REGISTRY_TOKEN=your_secret_token_here认证方式
Bearer Token(OAuth 2.0)
{
"@github": {
"url": "https://api.github.com/repos/org/registry/contents/{name}.json",
"headers": {
"Authorization": "Bearer ${GITHUB_TOKEN}"
}
}
}在 Headers 中使用 API Key
{
"@private": {
"url": "https://api.company.com/registry/{name}",
"headers": {
"X-API-Key": "${API_KEY}"
}
}
}基本认证
{
"@internal": {
"url": "https://registry.company.com/{name}.json",
"headers": {
"Authorization": "Basic ${BASE64_CREDENTIALS}"
}
}
}查询参数认证
{
"@secure": {
"url": "https://registry.example.com/{name}.json",
"params": {
"api_key": "${API_KEY}",
"client_id": "${CLIENT_ID}",
"signature": "${REQUEST_SIGNATURE}"
}
}
}多种认证方式
有些注册表需要同时使用多种认证方式:
{
"@enterprise": {
"url": "https://api.enterprise.com/v2/registry/{name}",
"headers": {
"Authorization": "Bearer ${ACCESS_TOKEN}",
"X-API-Key": "${API_KEY}",
"X-Workspace-Id": "${WORKSPACE_ID}"
},
"params": {
"version": "latest"
}
}
}安全注意事项
在使用命名空间注册表时,尤其是第三方或公开注册表时,安全性至关重要。我们是这样处理安全问题的:
资源校验
从注册表获取的所有资源在安装前都会根据注册表 item schema 进行校验。这可以确保:
- 结构校验:资源必须符合预期的 JSON schema
- 类型安全:资源类型会被验证(
registry:ui、registry:lib等) - 不会执行任意代码:资源是数据文件,而不是可执行脚本
环境变量安全
用于认证的环境变量:
- 不会被记录:CLI 从不记录或显示环境变量值
- 运行时展开:变量只会在需要时展开,不会被存储
- 按注册表隔离:每个注册表都维护自己的认证上下文
安全配置示例:
{
"registries": {
"@private": {
"url": "https://api.company.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${PRIVATE_REGISTRY_TOKEN}"
}
}
}
}不要把真实 token 提交到版本控制中。请使用 .env.local:
PRIVATE_REGISTRY_TOKEN=actual_token_here强制使用 HTTPS
我们强烈建议所有注册表 URL 都使用 HTTPS:
- 加密传输:防止中间人攻击
- 证书校验:确保你连接的是合法的注册表
- 凭据保护:headers 和 token 在传输过程中会被加密
{
"registries": {
"@secure": "https://registry.example.com/{name}.json", // ✅ Good
"@insecure": "http://registry.example.com/{name}.json" // ❌ Avoid
}
}内容安全
来自注册表的资源会被当作数据而不是代码处理:
- JSON parsing only: Resources must be valid JSON
- Schema validation: Must match the registry item schema
- File path restrictions: Files can only be written to configured paths
- No script execution: The CLI doesn't execute any code from registry resources
注册表信任模型
命名空间系统基于信任模型运行:
- 你要信任自己安装的内容:只把你信任的注册表添加到配置里
- 显式配置:注册表必须在
components.json中明确配置 - 不会自动发现注册表:CLI 不会自动添加注册表
- 依赖透明:所有依赖都会在注册表 item 中清晰列出
给注册表运营者的最佳实践
如果你在运行自己的注册表:
- 始终使用 HTTPS:不要通过 HTTP 提供注册表内容
- 实现认证:私有注册表要求 API key 或 token
- 限流:保护你的注册表免受滥用
- 内容校验:在提供资源之前先进行校验
安全注册表示例:
{
"@company": {
"url": "https://registry.company.com/v1/{name}.json",
"headers": {
"Authorization": "Bearer ${COMPANY_TOKEN}",
"X-Registry-Version": "1.0"
}
}
}安装前检查资源
CLI 会清楚展示将要安装的内容。你可以使用下面的命令查看某个注册表 item 的 payload:
pnpm dlx shadcn@latest view @acme/button
这会把该注册表 item 的 payload 输出到控制台。
依赖解析
基础依赖解析
资源可以依赖来自不同注册表的内容:
{
"name": "dashboard",
"type": "registry:block",
"registryDependencies": [
"@shadcn/card", // From default registry
"@v0/chart", // From v0 registry
"@acme/data-table", // From acme registry
"@lib/data-fetcher", // Utility library
"@ai/analytics-prompt" // AI prompt resource
]
}CLI 会自动从各自的注册表中解析并安装所有依赖。
高级依赖解析
如果你正在开发注册表,或者需要定制第三方资源,了解依赖在内部是如何解析的很重要。
解析流程
当你运行 npx shadcn@latest add @namespace/resource 时,CLI 会执行以下步骤:
- 清除注册表上下文,从干净状态开始
- 从指定注册表获取主资源
- 递归解析依赖,从各自的注册表中获取
- 应用拓扑排序,确保正确的安装顺序
- 根据目标路径去重文件(后者覆盖前者)
- 深度合并配置(tailwind、cssVars、css、envVars)
这意味着如果你运行下面的命令:
pnpm dlx shadcn@latest add @acme/auth @custom/login-form
@custom/login-form 中的 login-form.ts 会覆盖 @acme/auth 中的 login-form.ts,因为它是最后解析的。
覆盖第三方资源
你可以利用依赖解析流程来覆盖任何第三方资源:把它们添加到你自定义资源的 registryDependencies 中,然后用你自己的自定义值覆盖它们。
示例:定制第三方按钮
假设你想定制 vendor 注册表中的一个按钮:
1. 原始 vendor 按钮(@vendor/button):
{
"name": "button",
"type": "registry:ui",
"files": [
{
"path": "components/ui/button.tsx",
"type": "registry:ui",
"content": "// Vendor's button implementation\nexport function Button() { ... }"
}
],
"cssVars": {
"light": {
"--button-bg": "blue"
}
}
}2. 创建你自己的覆盖版本(@my-company/custom-button):
{
"name": "custom-button",
"type": "registry:ui",
"registryDependencies": [
"@vendor/button" // Import original first
],
"cssVars": {
"light": {
"--button-bg": "purple" // Override the color
}
}
}3. 安装你的自定义版本:
pnpm dlx shadcn@latest add @my-company/custom-button
这会先安装 @vendor/button 中的原始按钮,然后用你自己的自定义值覆盖 cssVars。
高级覆盖模式
扩展而不是替换
保留原始内容并添加扩展:
{
"name": "extended-table",
"registryDependencies": ["@vendor/table"],
"files": [
{
"path": "components/ui/table-extended.tsx",
"content": "import { Table } from '@vendor/table'\n// Add your extensions\nexport function ExtendedTable() { ... }"
}
]
}这会先安装 @vendor/table 中的原始表格,然后把你的扩展添加到 components/ui/table-extended.tsx。
局部覆盖(多文件资源)
只覆盖复杂组件中的某些文件:
{
"name": "custom-auth",
"registryDependencies": [
"@vendor/auth" // Has multiple files
],
"files": [
{
"path": "lib/auth-server.ts",
"type": "registry:lib",
"content": "// Your custom auth server"
}
]
}解析顺序示例
当你安装依赖多个资源的 @custom/dashboard 时:
{
"name": "dashboard",
"registryDependencies": [
"@shadcn/card", // 1. Resolved first
"@vendor/chart", // 2. Resolved second
"@custom/card" // 3. Resolved last (overrides @shadcn/card)
]
}解析顺序:
@shadcn/card- 安装到components/ui/card.tsx@vendor/chart- 安装到components/ui/chart.tsx@custom/card- 覆盖components/ui/card.tsx(如果目标路径相同)
解析的关键特性
- 来源追踪:每个资源都知道自己来自哪个注册表,从而避免命名冲突
- 防止循环依赖:自动检测并阻止循环依赖
- 智能安装顺序:先安装依赖,再安装使用这些依赖的资源
版本管理
你可以使用查询参数为注册表资源实现版本管理。这样用户就可以固定特定版本,或者使用不同的发布通道。
基础版本参数
{
"@versioned": {
"url": "https://registry.example.com/{name}",
"params": {
"version": "v2"
}
}
}这会将 @versioned/button 解析为:https://registry.example.com/button?version=v2
动态版本选择
使用环境变量来控制整个项目中的版本:
{
"@stable": {
"url": "https://registry.company.com/{name}",
"params": {
"version": "${REGISTRY_VERSION}"
}
}
}这让你可以:
- 在生产环境设置
REGISTRY_VERSION=v1.2.3 - 按环境覆盖(开发、预发布、生产)
语义化版本
用范围支持实现语义化版本:
{
"@npm-style": {
"url": "https://registry.example.com/{name}",
"params": {
"semver": "^2.0.0",
"prerelease": "${ALLOW_PRERELEASE}"
}
}
}版本解析最佳实践
- 使用环境变量 来在不同环境之间控制版本
- 使用
${VAR:-default}语法 提供合理默认值 - 清楚记录版本方案,方便注册表用户理解
- 支持版本固定,以便构建结果可复现
- 实现版本发现 端点(例如
/versions/{name}) - 对版本化资源使用合适的缓存头 做缓存
CLI 命令
shadcn CLI 提供了多个用于命名空间注册表的命令:
添加资源
从任何已配置的注册表安装资源:
# Install from a specific registry
npx shadcn@latest add @v0/dashboard
# Install multiple resources
npx shadcn@latest add @acme/button @lib/utils @ai/prompt
# Install from URL directly
npx shadcn@latest add https://registry.example.com/button.json
# Install from local file
npx shadcn@latest add ./local-registry/button.json查看资源
在安装前检查注册表 item:
# View a resource from a registry
npx shadcn@latest view @acme/button
# View multiple resources
npx shadcn@latest view @v0/dashboard @shadcn/card
# View from URL
npx shadcn@latest view https://registry.example.com/button.jsonview 命令会显示:
- Resource metadata (name, type, description)
- Dependencies and registry dependencies
- File contents that will be installed
- CSS variables and Tailwind configuration
- Required environment variables
搜索注册表
在注册表中搜索可用资源:
# Search a specific registry
npx shadcn@latest search @v0
# Search with query
npx shadcn@latest search @acme --query "auth"
# Search multiple registries
npx shadcn@latest search @v0 @acme @lib
# Limit results
npx shadcn@latest search @v0 --limit 10 --offset 20
# List all items (alias for search)
npx shadcn@latest list @acme搜索结果包含:
- Resource name and type
- Description
- Registry source
错误处理
注册表未配置
如果你引用了一个尚未配置的注册表:
pnpm dlx shadcn@latest add @non-existent/component
错误信息:
Unknown registry "@non-existent". Make sure it is defined in components.json as follows:
{
"registries": {
"@non-existent": "[URL_TO_REGISTRY]"
}
}缺少环境变量
如果必需的环境变量没有设置:
Registry "@private" requires the following environment variables:
• REGISTRY_TOKEN
Set the required environment variables to your .env or .env.local file.找不到资源
404 Not Found:
The item at https://registry.company.com/button.json was not found. It may not exist at the registry.这通常意味着:
- The resource name is misspelled
- The resource doesn't exist in the registry
- The registry URL pattern is incorrect
认证失败
401 Unauthorized:
You are not authorized to access the item at https://api.company.com/button.json
Check your authentication credentials and environment variables.403 Forbidden:
Access forbidden for https://api.company.com/button.json
Verify your API key has the necessary permissions.创建你自己的注册表
要让你的注册表兼容命名空间系统,你可以提供任何类型的资源 - 组件、库、工具、AI 提示、主题、配置,或者任何其他可共享的代码/内容:
-
实现注册表 item schema:你的注册表必须返回符合注册表 item schema 的 JSON。
-
支持 URL 模式:在 URL 模板中包含
{name},资源名会在这里插入。 -
定义资源类型:使用合适的
type字段来标识你的资源(例如registry:ui、registry:lib、registry:ai、registry:theme等)。 -
处理认证(如需要):支持通过 headers 或查询参数认证。
-
记录你的命名空间:为用户提供清晰的配置说明:
{
"registries": {
"@your-registry": "https://your-domain.com/r/{name}.json"
}
}技术细节
解析器模式
命名空间解析器使用以下正则表达式模式:
/^(@[a-zA-Z0-9](?:[a-zA-Z0-9-_]*[a-zA-Z0-9])?)\/(.+)$/这可以确保命名空间格式有效,并正确提取组件名称。
解析流程
- 解析:从
@namespace/component中提取命名空间和组件名称 - 查找:找到
@namespace对应的注册表配置 - 构建 URL:用实际值替换占位符
- 设置 Headers:如果已配置,则应用认证 headers
- 获取:从解析后的 URL 拉取组件
- 校验:确保响应符合注册表 item schema
- 解析依赖:递归获取任何注册表依赖
跨注册表依赖
当组件依赖来自不同注册表的内容时,解析器会:
- 为每个注册表维护独立的认证上下文
- 从各自的来源解析每个依赖
- 基于目标路径对文件去重
- 合并来自所有来源的配置(tailwind、cssVars 等)
最佳实践
- 对 API key 和 token 等敏感数据使用环境变量
- 为注册表使用唯一且有描述性的命名空间名称
- 清楚记录认证要求,方便用户理解
- 提供正确的错误响应,并附带有帮助的信息
- 尽可能缓存注册表响应,提升性能
- 如果组件有多个主题,支持样式变体
故障排查
找不到资源
- 确认注册表 URL 正确且可访问
- 检查 URL 中是否包含
{name}占位符 - 确认资源确实存在于注册表中
- 确认资源类型与注册表提供的内容一致
Authentication issues
- Confirm environment variables are set correctly
- Verify API keys/tokens are valid and not expired
- Check that headers are being sent in the correct format
Dependency conflicts
- Review resources with the same name from different registries
- Use fully qualified names (
@namespace/resource) to avoid ambiguity - Check for circular dependencies between registries
- Ensure resource types are compatible when mixing registries
本页目录
目录概览去中心化命名空间系统多注册表配置示例按资源类型按团队或部门按稳定性快速开始安装资源快速配置注册表命名规范配置基础配置高级配置URL 模式系统{name} 占位符(必需){style} 占位符(可选)认证与安全环境变量认证方式Bearer Token(OAuth 2.0)在 Headers 中使用 API Key基本认证查询参数认证多种认证方式安全注意事项资源校验环境变量安全强制使用 HTTPS内容安全注册表信任模型给注册表运营者的最佳实践安装前检查资源依赖解析基础依赖解析高级依赖解析解析流程覆盖第三方资源示例:定制第三方按钮高级覆盖模式扩展而不是替换局部覆盖(多文件资源)解析顺序示例解析的关键特性版本管理基础版本参数动态版本选择语义化版本版本解析最佳实践CLI 命令添加资源查看资源搜索注册表错误处理注册表未配置缺少环境变量找不到资源认证失败创建你自己的注册表技术细节解析器模式解析流程跨注册表依赖最佳实践故障排查找不到资源Authentication issuesDependency conflicts