or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

examples

edge-cases.mdreal-world-scenarios.md
index.md
tile.json

schemas.mddocs/reference/

Schemas and Validation

Comprehensive Zod schemas for configuration and registry validation. Provides runtime validation with TypeScript type inference for all configuration files, registry items, and API responses.

Capabilities

Configuration Schemas

Schemas for validating configuration files and settings.

registryConfigItemSchema

Validates single registry configuration. Supports both simple string URLs and advanced objects with authentication.

const registryConfigItemSchema: z.ZodUnion<[
  z.ZodString,  // Simple: "https://example.com/{name}.json"
  z.ZodObject<{
    url: z.ZodString        // Must include {name} placeholder
    params?: Record<string, string>
    headers?: Record<string, string>
  }>
]>

Simple Format: String URL with {name} placeholder

Advanced Format: Object with URL, query params, and headers for authentication

Usage Example:

import { registryConfigItemSchema } from 'shadcn/schema';

// Validate simple string format
const simple = registryConfigItemSchema.parse(
  'https://registry.example.com/{name}.json'
);

// Validate advanced format with auth
const advanced = registryConfigItemSchema.parse({
  url: 'https://registry.example.com/{name}.json',
  headers: {
    'Authorization': 'Bearer ${API_TOKEN}'
  },
  params: {
    'version': 'latest'
  }
});

registryConfigSchema

Validates registry configuration object. Maps registry namespaces to their configurations.

const registryConfigSchema: z.ZodRecord<
  z.ZodString,  // Key must start with @ (e.g., "@v0", "@acme")
  typeof registryConfigItemSchema
>

Usage Example:

import { registryConfigSchema } from 'shadcn/schema';

const config = registryConfigSchema.parse({
  '@shadcn': 'https://ui.shadcn.com/r/{name}.json',
  '@acme': {
    url: 'https://acme.com/registry/{name}.json',
    headers: {
      'Authorization': 'Bearer ${ACME_TOKEN}'
    }
  }
});

rawConfigSchema

Validates raw components.json configuration before path resolution.

const rawConfigSchema: z.ZodObject<{
  $schema?: string
  style: string
  rsc: boolean                     // Default: false
  tsx: boolean                     // Default: true
  tailwind: {
    config?: string
    css: string
    baseColor: string
    cssVariables: boolean          // Default: true
    prefix?: string                // Default: ""
  }
  iconLibrary?: string
  menuColor?: "default" | "inverted"  // Default: "default"
  menuAccent?: "subtle" | "bold"      // Default: "subtle"
  aliases: {
    components: string
    utils: string
    ui?: string
    lib?: string
    hooks?: string
  }
  registries?: RegistryConfig
}>

Usage Example:

import { rawConfigSchema } from 'shadcn/schema';

const config = rawConfigSchema.parse({
  style: 'new-york',
  rsc: false,
  tsx: true,
  tailwind: {
    css: 'app/globals.css',
    baseColor: 'slate',
    cssVariables: true
  },
  aliases: {
    components: '@/components',
    utils: '@/lib/utils'
  }
});

configSchema

Validates resolved configuration with paths. Extends rawConfigSchema with resolved absolute paths.

const configSchema: z.ZodObject<{
  // All fields from rawConfigSchema
  // Plus:
  resolvedPaths: {
    cwd: string
    tailwindConfig: string
    tailwindCss: string
    utils: string
    components: string
    lib: string
    hooks: string
    ui: string
  }
}>

Usage Example:

import { configSchema, type Config } from 'shadcn/schema';

const config: Config = configSchema.parse({
  style: 'new-york',
  rsc: false,
  tsx: true,
  tailwind: {
    css: 'app/globals.css',
    baseColor: 'slate',
    cssVariables: true
  },
  aliases: {
    components: '@/components',
    utils: '@/lib/utils',
    ui: '@/components/ui'
  },
  resolvedPaths: {
    cwd: '/project',
    tailwindConfig: '/project/tailwind.config.js',
    tailwindCss: '/project/app/globals.css',
    utils: '/project/lib/utils',
    components: '/project/components',
    ui: '/project/components/ui',
    lib: '/project/lib',
    hooks: '/project/hooks'
  }
});

workspaceConfigSchema

Validates workspace/monorepo configuration. Maps workspace keys to their configurations.

const workspaceConfigSchema: z.ZodRecord<string, typeof configSchema>

Usage Example:

import { workspaceConfigSchema } from 'shadcn/schema';

const workspaceConfig = workspaceConfigSchema.parse({
  'apps/web': {
    style: 'new-york',
    /* ... config ... */
    resolvedPaths: { /* ... */ }
  },
  'apps/docs': {
    style: 'default',
    /* ... config ... */
    resolvedPaths: { /* ... */ }
  }
});

Registry Item Schemas

Schemas for validating registry items and their components.

registryItemTypeSchema

Enum of valid registry item types.

const registryItemTypeSchema: z.ZodEnum<[
  "registry:lib",
  "registry:block",
  "registry:component",
  "registry:ui",
  "registry:hook",
  "registry:page",
  "registry:file",
  "registry:theme",
  "registry:style",
  "registry:item",
  "registry:base",
  "registry:font",
  "registry:example",    // Internal use only
  "registry:internal"    // Internal use only
]>

Usage Example:

import { registryItemTypeSchema } from 'shadcn/schema';

const type = registryItemTypeSchema.parse('registry:ui');

registryItemFileSchema

Validates registry item file. Discriminated union based on type.

const registryItemFileSchema: z.ZodDiscriminatedUnion<"type", [
  // registry:file and registry:page require target
  z.ZodObject<{
    path: string
    content?: string
    type: "registry:file" | "registry:page"
    target: string  // Required
  }>,
  // Other types have optional target
  z.ZodObject<{
    path: string
    content?: string
    type: RegistryItemType  // Excluding file and page
    target?: string
  }>
]>

Usage Example:

import { registryItemFileSchema } from 'shadcn/schema';

// UI component file
const componentFile = registryItemFileSchema.parse({
  path: 'components/ui/button.tsx',
  content: 'export function Button() { /* ... */ }',
  type: 'registry:ui'
});

// Page file with required target
const pageFile = registryItemFileSchema.parse({
  path: 'app/dashboard/page.tsx',
  content: 'export default function Dashboard() { /* ... */ }',
  type: 'registry:page',
  target: 'app/dashboard/page.tsx'
});

registryItemTailwindSchema

Validates Tailwind configuration for registry item.

const registryItemTailwindSchema: z.ZodObject<{
  config?: {
    content?: string[]
    theme?: Record<string, any>
    plugins?: string[]
  }
}>

Usage Example:

import { registryItemTailwindSchema } from 'shadcn/schema';

const tailwind = registryItemTailwindSchema.parse({
  config: {
    content: ['./components/**/*.tsx'],
    theme: {
      extend: {
        colors: {
          border: 'hsl(var(--border))'
        }
      }
    },
    plugins: ['@tailwindcss/typography']
  }
});

registryItemCssVarsSchema

Validates CSS variables for registry item.

const registryItemCssVarsSchema: z.ZodObject<{
  theme?: Record<string, string>
  light?: Record<string, string>
  dark?: Record<string, string>
}>

Usage Example:

import { registryItemCssVarsSchema } from 'shadcn/schema';

const cssVars = registryItemCssVarsSchema.parse({
  light: {
    'background': '0 0% 100%',
    'foreground': '222.2 84% 4.9%'
  },
  dark: {
    'background': '222.2 84% 4.9%',
    'foreground': '210 40% 98%'
  }
});

registryItemCssSchema

Validates CSS definitions for registry item. Supports recursive CSS property structures.

const registryItemCssSchema: z.ZodRecord<string, any>

Usage Example:

import { registryItemCssSchema } from 'shadcn/schema';

const css = registryItemCssSchema.parse({
  '@layer base': {
    ':root': {
      '--background': '0 0% 100%',
      '--foreground': '222.2 84% 4.9%'
    }
  }
});

registryItemEnvVarsSchema

Validates environment variables for registry item.

const registryItemEnvVarsSchema: z.ZodRecord<string, string>

Usage Example:

import { registryItemEnvVarsSchema } from 'shadcn/schema';

const envVars = registryItemEnvVarsSchema.parse({
  'NEXT_PUBLIC_API_URL': 'https://api.example.com',
  'API_SECRET_KEY': 'secret_key_here'
});

registryItemFontSchema

Validates font metadata for registry:font items.

const registryItemFontSchema: z.ZodObject<{
  family: string
  provider: "google"
  import: string
  variable: string
  weight?: string[]
  subsets?: string[]
}>

Usage Example:

import { registryItemFontSchema } from 'shadcn/schema';

const font = registryItemFontSchema.parse({
  family: 'Inter',
  provider: 'google',
  import: 'Inter',
  variable: '--font-inter',
  weight: ['400', '500', '600', '700'],
  subsets: ['latin']
});

registryItemCommonSchema

Common fields shared by all registry items.

const registryItemCommonSchema: z.ZodObject<{
  $schema?: string
  extends?: string
  name: string
  title?: string
  author?: string               // Min 2 characters
  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[]
}>

registryItemSchema

Complete registry item schema. Discriminated union by type for type-specific fields.

const registryItemSchema: z.ZodDiscriminatedUnion<"type", [
  // registry:base has config field
  z.ZodObject<{
    type: "registry:base"
    config?: Partial<RawConfig>
    // ...all common fields
  }>,
  // registry:font has font field
  z.ZodObject<{
    type: "registry:font"
    font: RegistryItemFont
    // ...all common fields
  }>,
  // Other types
  z.ZodObject<{
    type: RegistryItemType  // Excluding base and font
    // ...all common fields
  }>
]>

Usage Example:

import { registryItemSchema, type RegistryItem } from 'shadcn/schema';

// UI component
const button: RegistryItem = registryItemSchema.parse({
  name: 'button',
  type: 'registry:ui',
  description: 'A button component',
  dependencies: ['class-variance-authority'],
  registryDependencies: ['utils'],
  files: [
    {
      path: 'components/ui/button.tsx',
      type: 'registry:ui',
      content: '/* component code */'
    }
  ]
});

// Base item with config
const base = registryItemSchema.parse({
  name: 'base',
  type: 'registry:base',
  config: {
    tailwind: {
      cssVariables: true
    }
  }
});

// Font item
const fontItem = registryItemSchema.parse({
  name: 'inter',
  type: 'registry:font',
  font: {
    family: 'Inter',
    provider: 'google',
    import: 'Inter',
    variable: '--font-inter'
  }
});

registrySchema

Validates complete registry with metadata and items.

const registrySchema: z.ZodObject<{
  name: string
  homepage: string
  items: RegistryItem[]
}>

Usage Example:

import { registrySchema, type Registry } from 'shadcn/schema';

const registry: Registry = registrySchema.parse({
  name: 'shadcn',
  homepage: 'https://ui.shadcn.com',
  items: [
    {
      name: 'button',
      type: 'registry:ui',
      /* ... */
    },
    {
      name: 'card',
      type: 'registry:ui',
      /* ... */
    }
  ]
});

registryIndexSchema

Validates registry index (array of registry items).

const registryIndexSchema: z.ZodArray<typeof registryItemSchema>

Usage Example:

import { registryIndexSchema } from 'shadcn/schema';

const index = registryIndexSchema.parse([
  {
    name: 'button',
    type: 'registry:ui',
    description: 'A button component',
    registryDependencies: ['utils']
  },
  {
    name: 'card',
    type: 'registry:ui',
    description: 'A card component'
  }
]);

Additional Schemas

stylesSchema

Validates available styles from registry.

const stylesSchema: z.ZodArray<
  z.ZodObject<{
    name: string
    label: string
    description?: string
  }>
>

iconsSchema

Validates icon libraries configuration. Maps icon library names to their configuration objects (as string-to-string records).

const iconsSchema: z.ZodRecord<
  z.ZodString,  // Icon library name
  z.ZodRecord<z.ZodString, z.ZodString>  // Configuration as key-value pairs
>

Structure: Record<string, Record<string, string>> - Nested record where each icon library is mapped to its configuration properties as key-value string pairs.

registryBaseColorSchema

Validates base color configuration with inline colors and CSS variables.

const registryBaseColorSchema: z.ZodObject<{
  inlineColors: z.ZodObject<{
    light: z.ZodRecord<z.ZodString, z.ZodString>
    dark: z.ZodRecord<z.ZodString, z.ZodString>
  }>
  cssVars: RegistryItemCssVars
  cssVarsV4?: RegistryItemCssVars  // Optional
  inlineColorsTemplate: z.ZodString
  cssVarsTemplate: z.ZodString
}>

Fields:

  • inlineColors - Inline color definitions for light and dark themes
  • cssVars - CSS variable definitions using RegistryItemCssVars schema
  • cssVarsV4 - Optional CSS variables for v4 compatibility
  • inlineColorsTemplate - Template string for inline colors
  • cssVarsTemplate - Template string for CSS variables

registryResolvedItemsTreeSchema

Validates resolved items tree with dependencies and all component metadata. Includes all fields from registryItemCommonSchema that are needed for installation.

const registryResolvedItemsTreeSchema: z.ZodObject<{
  dependencies?: string[]
  devDependencies?: string[]
  files?: RegistryItemFile[]
  tailwind?: RegistryItemTailwind
  cssVars?: RegistryItemCssVars
  css?: RegistryItemCss
  envVars?: Record<string, string>
  docs?: string
  fonts?: Array<RegistryFontItem>  // Optional, for font items
}>

Fields:

  • dependencies - npm package dependencies
  • devDependencies - npm dev dependencies
  • files - Component files to install
  • tailwind - Tailwind configuration updates
  • cssVars - CSS variable definitions
  • css - CSS content to add
  • envVars - Environment variables required
  • docs - Documentation URL or content
  • fonts - Font items (optional, for components that include fonts)

searchResultItemSchema

Validates single search result item.

const searchResultItemSchema: z.ZodObject<{
  name: string
  type?: string
  description?: string
  registry: string
  addCommandArgument: string
}>

searchResultsSchema

Validates search results with pagination metadata.

const searchResultsSchema: z.ZodObject<{
  pagination: {
    total: number
    offset: number
    limit: number
    hasMore: boolean
  }
  items: SearchResultItem[]
}>

registriesIndexSchema

Validates registries index listing available registries. Maps registry namespace names to their URLs.

const registriesIndexSchema: z.ZodRecord<
  z.ZodString,  // Namespace (must match /^@[a-zA-Z0-9][a-zA-Z0-9-_]*$/)
  z.ZodString   // Registry URL
>

Structure: Record<string, string> - Maps registry namespace (e.g., @shadcn) to registry URL. The namespace key must start with @ and contain only alphanumeric characters, hyphens, and underscores.

presetSchema

Validates preset configuration for project initialization. Contains all settings for a complete shadcn/ui preset.

const presetSchema: z.ZodObject<{
  name: string
  title: string
  description: string
  base: string
  style: string
  baseColor: string
  theme: string
  iconLibrary: string
  font: string
  menuAccent: "subtle" | "bold"
  menuColor: "default" | "inverted"
  radius: string
}>

Fields:

  • name - Preset identifier (e.g., "default", "new-york")
  • title - Display title for the preset
  • description - Preset description
  • base - Base configuration preset
  • style - UI style (e.g., "default", "new-york")
  • baseColor - Base color palette (e.g., "slate", "zinc")
  • theme - Theme name
  • iconLibrary - Icon library to use (e.g., "lucide", "phosphor")
  • font - Font configuration
  • menuAccent - Menu accent style
  • menuColor - Menu color scheme
  • radius - Border radius value

configJsonSchema

Validates config.json from registry containing presets.

const configJsonSchema: z.ZodObject<{
  presets: Preset[]
}>

TypeScript Types

All schemas have corresponding TypeScript types inferred via z.infer<>:

// Infer types from schemas
type RegistryItem = z.infer<typeof registryItemSchema>
type RegistryBaseItem = Extract<RegistryItem, { type: "registry:base" }>
type RegistryFontItem = Extract<RegistryItem, { type: "registry:font" }>
type Registry = z.infer<typeof registrySchema>
type RegistryIndex = z.infer<typeof registryIndexSchema>
type RegistryResolvedItemsTree = z.infer<typeof registryResolvedItemsTreeSchema>
type Config = z.infer<typeof configSchema>
type RawConfig = z.infer<typeof rawConfigSchema>
type RegistryConfig = z.infer<typeof registryConfigSchema>
type SearchResults = z.infer<typeof searchResultsSchema>
type SearchResultItem = z.infer<typeof searchResultItemSchema>
type RegistriesIndex = z.infer<typeof registriesIndexSchema>
type RegistryBaseColor = z.infer<typeof registryBaseColorSchema>
type Style = z.infer<typeof stylesSchema>[number]
type Icons = z.infer<typeof iconsSchema>
type Preset = z.infer<typeof presetSchema>
type ConfigJson = z.infer<typeof configJsonSchema>

// Registry item sub-types
type RegistryItemFile = z.infer<typeof registryItemFileSchema>
type RegistryItemTailwind = z.infer<typeof registryItemTailwindSchema>
type RegistryItemCssVars = z.infer<typeof registryItemCssVarsSchema>
type RegistryItemCss = z.infer<typeof registryItemCssSchema>
type RegistryItemEnvVars = z.infer<typeof registryItemEnvVarsSchema>
type RegistryItemFont = z.infer<typeof registryItemFontSchema>
type RegistryItemType = z.infer<typeof registryItemTypeSchema>

// Import types directly
import type {
  RegistryItem,
  RegistryBaseItem,
  RegistryFontItem,
  Registry,
  RegistryIndex,
  RegistryResolvedItemsTree,
  Config,
  RawConfig,
  RegistryConfig,
  SearchResults,
  SearchResultItem,
  RegistriesIndex,
  RegistryBaseColor,
  Preset,
  ConfigJson,
  RegistryItemFile,
  RegistryItemTailwind,
  RegistryItemCssVars,
  RegistryItemCss,
  RegistryItemEnvVars,
  RegistryItemFont,
  RegistryItemType
} from 'shadcn/schema';

Usage Patterns

Validating User Input

import { configSchema } from 'shadcn/schema';

try {
  const config = configSchema.parse(userInput);
  // Config is valid and typed
} catch (error) {
  if (error instanceof z.ZodError) {
    console.error('Validation errors:', error.errors);
    // error.errors is an array of ZodIssue objects
    // Each issue has: path, message, code, etc.
  }
}

Safe Parsing

import { registryItemSchema } from 'shadcn/schema';

const result = registryItemSchema.safeParse(data);

if (result.success) {
  // result.data is typed RegistryItem
  console.log(result.data.name);
} else {
  // result.error contains validation errors
  console.error(result.error.errors);
  // result.error is a ZodError with detailed validation issues
}

Type Guards

import { type RegistryItem } from 'shadcn/schema';

function isFontItem(item: RegistryItem): item is RegistryFontItem {
  return item.type === 'registry:font';
}

function isBaseItem(item: RegistryItem): item is RegistryBaseItem {
  return item.type === 'registry:base';
}

// Usage
if (isFontItem(item)) {
  console.log(item.font.family); // TypeScript knows font exists
}

Partial Validation

import { registryItemSchema } from 'shadcn/schema';

// Validate only specific fields
const partialSchema = registryItemSchema.pick({ name: true, type: true });
const result = partialSchema.parse({ name: 'button', type: 'registry:ui' });

Custom Validation

import { z } from 'zod';
import { registryItemSchema } from 'shadcn/schema';

// Add custom validation
const customSchema = registryItemSchema.refine(
  (item) => item.files && item.files.length > 0,
  {
    message: "Item must have at least one file"
  }
);

Error Handling

Zod validation errors provide detailed information:

import { configSchema } from 'shadcn/schema';
import { z } from 'zod';

try {
  const config = configSchema.parse(invalidConfig);
} catch (error) {
  if (error instanceof z.ZodError) {
    error.errors.forEach((issue) => {
      console.error(`Path: ${issue.path.join('.')}`);
      console.error(`Message: ${issue.message}`);
      console.error(`Code: ${issue.code}`);
    });
  }
}

Common Zod Error Codes:

  • invalid_type - Type mismatch
  • invalid_string - String validation failed
  • too_small - Value too small (min length, etc.)
  • too_big - Value too large (max length, etc.)
  • invalid_enum_value - Value not in enum
  • custom - Custom validation error

Agent Integration Patterns

Validating Registry Responses

import { registryItemSchema } from 'shadcn/schema';
import { getRegistryItems } from 'shadcn';

async function safeGetRegistryItems(items: string[]) {
  const rawItems = await getRegistryItems(items);
  
  // Validate each item
  return rawItems.map(item => {
    const result = registryItemSchema.safeParse(item);
    if (!result.success) {
      throw new Error(`Invalid registry item: ${result.error.message}`);
    }
    return result.data;
  });
}

Validating Configuration Files

import { rawConfigSchema, configSchema } from 'shadcn/schema';
import { readFile } from 'fs/promises';
import { resolve } from 'path';

async function loadAndValidateConfig(cwd: string) {
  const configPath = resolve(cwd, 'components.json');
  const raw = await readFile(configPath, 'utf-8');
  const json = JSON.parse(raw);
  
  // Validate raw config
  const rawConfig = rawConfigSchema.parse(json);
  
  // Resolve paths and validate full config
  // (path resolution logic here)
  const config = configSchema.parse({
    ...rawConfig,
    resolvedPaths: { /* ... */ }
  });
  
  return config;
}