Programmatic API for fetching and resolving components from registries. The Registry API provides functions for retrieving components, resolving dependencies, searching across registries, and managing registry configurations.
Fetches registry items by name. Retrieves one or more items from configured registries without resolving dependencies.
/**
* Fetch registry items by name
* @param items - Array of item names (e.g., ['@shadcn/button', '@acme/card'])
* @param options - Optional configuration and caching options
* @returns Promise resolving to array of registry items
* @throws RegistryNotFoundError if item not found
* @throws RegistryNotConfiguredError if registry not configured
* @throws RegistryFetchError on network errors
*/
function getRegistryItems(
items: string[],
options?: {
config?: Partial<Config>
useCache?: boolean
}
): Promise<RegistryItem[]>Parameters:
items: string[] - Array of registry item names with namespace prefix (e.g., ['@shadcn/button']). Required, must not be empty.options.config?: Partial<Config> - Optional configuration override. Merges with existing config from components.json.options.useCache?: boolean - Whether to use HTTP cache (default: false). When true, uses cached responses when available.Returns: Promise<RegistryItem[]> - Array of fetched registry items in the same order as input.
Throws:
RegistryNotFoundError - If item or registry not foundRegistryNotConfiguredError - If registry not configured in components.jsonRegistryFetchError - On network or fetch errorsConfigMissingError - If components.json not foundUsage Example:
import { getRegistryItems } from 'shadcn';
// Fetch single item
const [button] = await getRegistryItems(['@shadcn/button']);
// Fetch multiple items
const items = await getRegistryItems([
'@shadcn/button',
'@shadcn/card',
'@acme/special-input'
]);
// With custom config
const items = await getRegistryItems(['@shadcn/button'], {
config: {
registries: {
'@acme': 'https://custom.registry.com/{name}.json'
}
}
});
// With caching enabled
const items = await getRegistryItems(['@shadcn/button'], {
useCache: true
});
// Access item properties
console.log(items[0].name); // 'button'
console.log(items[0].type); // 'registry:ui'
console.log(items[0].files); // Array of file objects
console.log(items[0].dependencies); // Array of npm packagesError Handling:
import { getRegistryItems } from 'shadcn';
import { RegistryNotFoundError, RegistryNotConfiguredError } from 'shadcn/registry';
try {
const items = await getRegistryItems(['@custom/button']);
} catch (error) {
if (error instanceof RegistryNotFoundError) {
// Item or registry not found
console.error('Not found:', error.message);
if (error.suggestion) {
console.log('Suggestion:', error.suggestion);
}
} else if (error instanceof RegistryNotConfiguredError) {
// Registry not in components.json
console.error('Registry not configured:', error.context?.registry);
} else {
throw error;
}
}Resolves registry items with all dependencies. Fetches items and recursively resolves all registry dependencies, returning a complete dependency tree.
/**
* Resolve registry items with all dependencies
* @param items - Array of item names to resolve
* @param options - Optional configuration and caching options
* @returns Promise resolving to items tree with dependencies
* @throws RegistryNotFoundError if item or dependency not found
* @throws RegistryNotConfiguredError if registry not configured
*/
function resolveRegistryItems(
items: string[],
options?: {
config?: Partial<Config>
useCache?: boolean
}
): Promise<RegistryResolvedItemsTree>Parameters:
items: string[] - Array of registry item names. Required, must not be empty.options.config?: Partial<Config> - Optional configuration override.options.useCache?: boolean - Whether to use HTTP cache (default: false).Returns: Promise<RegistryResolvedItemsTree> - Resolved items tree with all dependencies, including:
dependencies?: string[] - Flattened npm dependenciesdevDependencies?: string[] - Flattened npm dev dependenciesfiles?: RegistryItemFile[] - All files from items and dependenciestailwind?: RegistryItemTailwind - Merged Tailwind configurationcssVars?: RegistryItemCssVars - Merged CSS variablescss?: RegistryItemCss - Merged CSS contentenvVars?: Record<string, string> - Merged environment variablesdocs?: string - Documentationfonts?: RegistryFontItem[] - Font itemsThrows:
RegistryNotFoundError - If item or dependency not foundRegistryNotConfiguredError - If registry not configuredConfigMissingError - If components.json not foundUsage Example:
import { resolveRegistryItems } from 'shadcn';
// Resolve item with dependencies
const resolved = await resolveRegistryItems(['@shadcn/button']);
// Resolved tree includes the item and all its dependencies
console.log(resolved.items); // Array of all items including deps
console.log(resolved.dependencies); // Flattened npm dependencies
// Example: button might depend on utils, which is automatically included
const result = await resolveRegistryItems(['@shadcn/dialog']);
// Result includes: dialog, button (dep), utils (transitive dep)Dependency Resolution:
registryDependencies from each itemCircular Dependency Handling:
Gets a registry by name or URL. Fetches complete registry metadata including all available items.
/**
* Get a registry by name or URL
* @param name - Registry name (with @ prefix) or full URL
* @param options - Optional configuration and caching options
* @returns Promise resolving to registry object
* @throws RegistryInvalidNamespaceError if name doesn't start with @ (when not URL)
* @throws RegistryNotFoundError if registry is not found
* @throws RegistryParseError if registry response is invalid
*/
function getRegistry(
name: string,
options?: {
config?: Partial<Config>
useCache?: boolean
}
): Promise<Registry>Parameters:
name: string - Registry name (e.g., '@shadcn') or URL (e.g., 'https://ui.shadcn.com/r/registry'). If name, must start with @.options.config?: Partial<Config> - Optional configuration override.options.useCache?: boolean - Whether to use HTTP cache (default: false).Returns: Promise<Registry> - Registry object with:
name: string - Registry namehomepage: string - Registry homepage URLitems: RegistryItem[] - Array of all available itemsThrows:
RegistryInvalidNamespaceError - If name doesn't start with @ (when not URL)RegistryNotFoundError - If registry is not foundRegistryParseError - If registry response is invalidRegistryNotConfiguredError - If registry name not in config (when using name)Usage Example:
import { getRegistry } from 'shadcn';
// Get registry by name
const registry = await getRegistry('@shadcn');
console.log(registry.name); // 'shadcn'
console.log(registry.homepage); // 'https://ui.shadcn.com'
console.log(registry.items); // Array of all available items
// Get registry by URL
const customRegistry = await getRegistry(
'https://custom.registry.com/registry.json'
);
// With caching
const registry = await getRegistry('@shadcn', { useCache: true });
// Browse available items
registry.items.forEach(item => {
console.log(item.name, item.type, item.description);
});URL Format:
{name} placeholder for item-specific requestshttps://ui.shadcn.com/r/{name}.jsonGets the registries index listing all available public registries. Fetches the central index of known registries.
/**
* Get the registries index
* @param options - Optional caching options
* @returns Promise resolving to registries index
* @throws RegistriesIndexParseError if index response is invalid
*/
function getRegistriesIndex(
options?: { useCache?: boolean }
): Promise<RegistriesIndex>Parameters:
options.useCache?: boolean - Whether to use HTTP cache (default: true). Caching is enabled by default for index.Returns: Promise<RegistriesIndex> - Record mapping registry namespace to URL:
type RegistriesIndex = Record<string, string>
// Example: { "@shadcn": "https://ui.shadcn.com/r/{name}.json" }Throws:
RegistriesIndexParseError - If index response is invalidRegistryFetchError - On network errorsUsage Example:
import { getRegistriesIndex } from 'shadcn';
// Get list of all public registries
const index = await getRegistriesIndex();
// Browse available registries
Object.entries(index).forEach(([name, url]) => {
console.log(name); // Registry name (e.g., '@shadcn')
console.log(url); // Registry URL
});
// Without cache
const freshIndex = await getRegistriesIndex({ useCache: false });Searches items across multiple registries with fuzzy matching. Performs fuzzy search on item names and descriptions with pagination support.
/**
* Search items across registries with fuzzy matching
* @param registries - Array of registry names to search
* @param options - Search query, pagination, config, and caching options
* @returns Promise resolving to search results with pagination
* @throws RegistryNotConfiguredError if registry not configured
*/
function searchRegistries(
registries: string[],
options?: {
query?: string
limit?: number
offset?: number
config?: Partial<Config>
useCache?: boolean
}
): Promise<SearchResults>Parameters:
registries: string[] - Array of registry names to search (e.g., ['@shadcn', '@acme']). Required, must not be empty. Must start with @.options.query?: string - Search query for fuzzy matching. Optional - omit to list all items.options.limit?: number - Maximum items to return. Optional, default varies by registry.options.offset?: number - Pagination offset. Optional, default: 0.options.config?: Partial<Config> - Optional configuration override.options.useCache?: boolean - Whether to use HTTP cache (default: false).Returns: Promise<SearchResults> - Search results with:
interface SearchResults {
pagination: {
total: number
offset: number
limit: number
hasMore: boolean
}
items: SearchResultItem[]
}
interface SearchResultItem {
name: string
type?: string
description?: string
registry: string
addCommandArgument: string // Full name for add command (e.g., '@shadcn/button')
}Throws:
RegistryNotConfiguredError - If registry not configuredRegistryInvalidNamespaceError - If registry name doesn't start with @Usage Example:
import { searchRegistries } from 'shadcn/registry';
// Search for "button" across registries
const results = await searchRegistries(['@shadcn'], {
query: 'button'
});
console.log(results.pagination.total); // Total matches
console.log(results.pagination.hasMore); // More results available?
console.log(results.items); // Array of matching items
// List all items (no query)
const allItems = await searchRegistries(['@shadcn']);
// With pagination
const firstPage = await searchRegistries(['@shadcn'], {
query: 'form',
limit: 10,
offset: 0
});
const secondPage = await searchRegistries(['@shadcn'], {
query: 'form',
limit: 10,
offset: 10
});
// Search multiple registries
const multiResults = await searchRegistries(
['@shadcn', '@acme', '@custom'],
{ query: 'input' }
);
// Access search result items
results.items.forEach(item => {
console.log(item.name); // Item name
console.log(item.type); // Item type
console.log(item.description); // Description
console.log(item.registry); // Source registry
console.log(item.addCommandArgument); // Full name for add command
});Fuzzy Matching:
Gets registries configuration from components.json. Loads and merges built-in and user-configured registries.
/**
* Get registries configuration from components.json
* @param cwd - Working directory containing components.json
* @param options - Optional caching options
* @returns Promise resolving to registries config
* @throws ConfigMissingError if components.json not found
* @throws ConfigParseError if components.json is invalid
*/
function getRegistriesConfig(
cwd: string,
options?: { useCache?: boolean }
): Promise<{ registries: RegistryConfig }>Parameters:
cwd: string - Working directory path. Searches for components.json in this directory and parent directories.options.useCache?: boolean - Whether to use config cache (default: true). Caching is enabled by default.Returns: Promise<{ registries: RegistryConfig }> - Merged registries configuration:
type RegistryConfig = Record<string, string | RegistryConfigItem>
interface RegistryConfigItem {
url: string
params?: Record<string, string>
headers?: Record<string, string>
}Throws:
ConfigMissingError - If components.json not foundConfigParseError - If components.json is invalid JSON or schemaUsage Example:
import { getRegistriesConfig } from 'shadcn';
// Get registries from current directory
const { registries } = await getRegistriesConfig(process.cwd());
console.log(Object.keys(registries)); // ['@shadcn', '@acme', ...]
// Access registry config
const shadcnConfig = registries['@shadcn'];
// Can be string URL or object with url, headers, params
// Without cache
const fresh = await getRegistriesConfig(process.cwd(), { useCache: false });Configuration Merging:
@shadcnGets the shadcn registry index. Fetches the official shadcn/ui component index.
/**
* Get the shadcn registry index
* @returns Promise resolving to registry index
* @throws RegistryFetchError on network errors
* @throws RegistryParseError if index response is invalid
*/
function getShadcnRegistryIndex(): Promise<RegistryIndex>Returns: Promise<RegistryIndex> - Array of registry item metadata (RegistryItem[] without full file content).
Throws:
RegistryFetchError - On network errorsRegistryParseError - If index response is invalidUsage Example:
import { getShadcnRegistryIndex } from 'shadcn';
// Get shadcn component index
const index = await getShadcnRegistryIndex();
// Browse available components
index.forEach(item => {
console.log(item.name); // Component name
console.log(item.type); // Item type
console.log(item.description); // Description
console.log(item.registryDependencies); // Registry deps
console.log(item.dependencies); // npm deps
});
// Find specific component
const button = index.find(item => item.name === 'button');Note: This function fetches the index directly from shadcn registry, bypassing local configuration.
Gets available style options from registry. Fetches the list of available visual styles (e.g., 'default', 'new-york').
/**
* Get available registry styles
* @returns Promise resolving to array of style objects
* @throws RegistryFetchError on network errors
*/
function getRegistryStyles(): Promise<Style[]>Returns: Promise<Style[]> - Array of available styles:
interface Style {
name: string
label: string
description?: string
}Throws:
RegistryFetchError - On network errorsUsage Example:
import { getRegistryStyles } from 'shadcn';
// Get available styles
const styles = await getRegistryStyles();
styles.forEach(style => {
console.log(style.name); // 'default', 'new-york'
console.log(style.label); // Display name
console.log(style.description); // Style description
});Gets available icon libraries from registry. Fetches the list of supported icon library configurations.
/**
* Get available icon libraries
* @returns Promise resolving to icons object
* @throws RegistryFetchError on network errors
*/
function getRegistryIcons(): Promise<Icons>Returns: Promise<Icons> - Object mapping icon library names to metadata:
type Icons = Record<string, IconLibrary>
interface IconLibrary {
name: string
title: string
packages: string[]
import: string
usage: string
export: string
}Throws:
RegistryFetchError - On network errorsUsage Example:
import { getRegistryIcons } from 'shadcn';
// Get available icon libraries
const icons = await getRegistryIcons();
console.log(Object.keys(icons)); // ['lucide', 'tabler', 'hugeicons', 'phosphor']
// Access icon library config
const lucide = icons.lucide;
console.log(lucide.name); // 'lucide'
console.log(lucide.packages); // ['lucide-react']
console.log(lucide.import); // Import pattern
console.log(lucide.usage); // Usage patternGets available base color options. Returns the list of base color choices for theming.
/**
* Get available base colors
* @returns Promise resolving to array of base color objects
* @throws RegistryFetchError on network errors
*/
function getRegistryBaseColors(): Promise<BaseColor[]>Returns: Promise<BaseColor[]> - Array of base color objects:
interface BaseColor {
name: string
label: string
}Throws:
RegistryFetchError - On network errorsUsage Example:
import { getRegistryBaseColors } from 'shadcn';
// Get available base colors
const colors = await getRegistryBaseColors();
console.log(colors);
// [
// { name: 'neutral', label: 'Neutral' },
// { name: 'gray', label: 'Gray' },
// { name: 'zinc', label: 'Zinc' },
// { name: 'stone', label: 'Stone' },
// { name: 'slate', label: 'Slate' }
// ]Gets specific base color configuration. Fetches the CSS variable definitions for a base color.
/**
* Get specific base color configuration
* @param baseColor - Base color name (e.g., 'slate')
* @returns Promise resolving to base color config with CSS variables
* @throws RegistryNotFoundError if base color not found
* @throws RegistryFetchError on network errors
*/
function getRegistryBaseColor(
baseColor: string
): Promise<RegistryBaseColor>Parameters:
baseColor: string - Base color name (e.g., 'slate', 'zinc'). Required.Returns: Promise<RegistryBaseColor> - Base color configuration object:
interface RegistryBaseColor {
name: string
label: string
inlineColors?: Record<string, string>
cssVars?: {
light?: Record<string, string>
dark?: Record<string, string>
}
templates?: {
shadcn?: string
new_york?: string
}
}Throws:
RegistryNotFoundError - If base color not foundRegistryFetchError - On network errorsUsage Example:
import { getRegistryBaseColor } from 'shadcn';
// Get slate color configuration
const slate = await getRegistryBaseColor('slate');
console.log(slate.name); // 'slate'
console.log(slate.label); // 'Slate'
console.log(slate.cssVars); // CSS variable definitions
// CSS vars structure
console.log(slate.cssVars.light); // Light theme variables
console.log(slate.cssVars.dark); // Dark theme variablesGets available presets for initialization. Fetches preset configurations that can be used with init command.
/**
* Get available presets
* @param options - Optional caching options
* @returns Promise resolving to array of presets
* @throws RegistryFetchError on network errors
*/
function getPresets(
options?: { useCache?: boolean }
): Promise<Preset[]>Parameters:
options.useCache?: boolean - Whether to use HTTP cache (default: true). Caching is enabled by default.Returns: Promise<Preset[]> - Array of preset configurations:
interface Preset {
name: string
label: string
description?: string
config: Partial<Config>
}Throws:
RegistryFetchError - On network errorsUsage Example:
import { getPresets } from 'shadcn';
// Get available presets
const presets = await getPresets();
presets.forEach(preset => {
console.log(preset.name); // Preset name
console.log(preset.label); // Display name
console.log(preset.description); // Description
console.log(preset.config); // Configuration object
});Gets a specific preset by name. Fetches a single preset configuration.
/**
* Get specific preset by name
* @param name - Preset name
* @param options - Optional caching options
* @returns Promise resolving to preset or null if not found
* @throws RegistryFetchError on network errors
*/
function getPreset(
name: string,
options?: { useCache?: boolean }
): Promise<Preset | null>Parameters:
name: string - Preset name (case-insensitive). Required.options.useCache?: boolean - Whether to use HTTP cache (default: true).Returns: Promise<Preset | null> - Preset object or null if not found.
Throws:
RegistryFetchError - On network errorsUsage Example:
import { getPreset } from 'shadcn';
// Get specific preset
const preset = await getPreset('default');
if (preset) {
console.log(preset.name); // 'default'
console.log(preset.config); // Configuration object
}These functions are deprecated and will be removed in a future version:
Resolves component dependency tree from registry index.
/**
* @deprecated Use resolveRegistryItems instead
*/
function resolveTree(
index: RegistryIndex,
names: string[]
): Promise<RegistryIndex>Fetches registry items from dependency tree.
/**
* @deprecated Use getRegistryItems with resolved names instead
*/
function fetchTree(
style: string,
tree: RegistryIndex
): Promise<RegistryItem[]>Gets target path for registry item installation.
/**
* @deprecated Path resolution is handled internally
*/
function getItemTargetPath(
config: Config,
item: Pick<RegistryItem, "type">,
override?: string
): Promise<string | null>// Registry item type
interface RegistryItem {
name: string
type: RegistryItemType
description?: string
dependencies?: string[]
devDependencies?: string[]
registryDependencies?: string[]
files?: RegistryItemFile[]
tailwind?: RegistryItemTailwind
cssVars?: RegistryItemCssVars
css?: RegistryItemCss
envVars?: Record<string, string>
meta?: Record<string, any>
docs?: string
categories?: string[]
}
// Registry type
interface Registry {
name: string
homepage: string
items: RegistryItem[]
}
// Search results type
interface SearchResults {
pagination: {
total: number
offset: number
limit: number
hasMore: boolean
}
items: SearchResultItem[]
}
// Search result item
interface SearchResultItem {
name: string
type?: string
description?: string
registry: string
addCommandArgument: string
}
// Registry resolved items tree
interface RegistryResolvedItemsTree {
dependencies?: string[]
devDependencies?: string[]
files?: RegistryItemFile[]
tailwind?: RegistryItemTailwind
cssVars?: RegistryItemCssVars
css?: RegistryItemCss
envVars?: Record<string, string>
docs?: string
fonts?: RegistryFontItem[]
}
// Configuration type
interface Config {
style: string
rsc: boolean
tsx: boolean
tailwind: {
config?: string
css: string
baseColor: string
cssVariables: boolean
prefix?: string
}
aliases: {
components: string
utils: string
ui?: string
lib?: string
hooks?: string
}
registries?: RegistryConfig
resolvedPaths: {
cwd: string
tailwindConfig: string
tailwindCss: string
utils: string
components: string
lib: string
hooks: string
ui: string
}
}
// Registry configuration
type RegistryConfig = Record<string, string | RegistryConfigItem>
interface RegistryConfigItem {
url: string
params?: Record<string, string>
headers?: Record<string, string>
}
// Registry index (array of registry items)
type RegistryIndex = RegistryItem[]
// Style configuration
interface Style {
name: string
label: string
description?: string
}
// Icons configuration
type Icons = Record<string, IconLibrary>
interface IconLibrary {
name: string
title: string
packages: string[]
import: string
usage: string
export: string
}
// Base color types
interface BaseColor {
name: string
label: string
}
interface RegistryBaseColor {
name: string
label: string
inlineColors?: Record<string, string>
cssVars?: {
light?: Record<string, string>
dark?: Record<string, string>
}
templates?: {
shadcn?: string
new_york?: string
}
}
// Registries index
type RegistriesIndex = Record<string, string>
// Preset configuration
interface Preset {
name: string
label: string
description?: string
config: Partial<Config>
}All registry functions may throw specific registry errors. See the main documentation for error types and handling.
Common Error Patterns:
import {
getRegistryItems,
RegistryError,
RegistryNotFoundError,
RegistryNotConfiguredError,
ConfigMissingError
} from 'shadcn/registry';
async function safeRegistryOperation() {
try {
const items = await getRegistryItems(['@shadcn/button']);
return items;
} catch (error) {
if (error instanceof ConfigMissingError) {
throw new Error('Project not initialized. Run: npx shadcn init');
} else if (error instanceof RegistryNotConfiguredError) {
throw new Error(`Registry not configured: ${error.context?.registry}`);
} else if (error instanceof RegistryNotFoundError) {
throw new Error(`Item not found: ${error.message}`);
} else if (error instanceof RegistryError) {
throw new Error(`Registry error: ${error.code} - ${error.message}`);
}
throw error;
}
}