Understanding the components.json Configuration File in shadcn-ui: Schema, Purpose, and Examples

The components.json file serves as the single source of truth for the shadcn-ui CLI, defining project structure, Tailwind settings, path aliases, and component registries to enable automated component installation and migration.

The components.json configuration file in shadcn-ui is the central hub that powers the CLI tooling for the popular React component library. Located in the shadcn-ui/ui repository, this JSON file tells the CLI exactly how your project is structured, which styling conventions you follow, and where to install components. Without this file, commands like npx shadcn add would lack the context needed to resolve paths or apply the correct Tailwind configuration.

What Is the Purpose of components.json?

The primary purpose of the components.json file is to act as the single source of truth for the shadcn-ui CLI during component scaffolding and project migration. When you execute CLI commands such as npx shadcn init, shadcn add, or shadcn migrate, the tool performs a hierarchical search upward from the current working directory to locate this configuration file, as implemented in packages/shadcn/src/utils/get-config.ts (lines 24-27).

Once discovered, the CLI validates the file's structure against a strict JSON-Schema definition stored at deprecated/www/public/schema.json. This validation ensures that required fields like style, tailwind, and aliases are present and correctly typed before the CLI attempts to resolve paths or install components. If validation fails, the CLI invokes error handlers from packages/shadcn/src/registry/errors.ts to provide actionable feedback, such as missing required fields or invalid alias paths.

Core Schema and Configuration Fields

The schema for the components.json configuration file in shadcn-ui defines specific fields that control everything from Tailwind integration to module resolution. All fields are required except registries and the optional Tailwind prefix.

Project Metadata

  • style: A string specifying the default component style, such as "default" or "new-york". This determines which visual variant the CLI installs.
  • rsc: Boolean flag indicating whether the project uses React Server Components. When true, the CLI generates server-compatible code.
  • tsx: Boolean flag indicating TypeScript usage. When true, components are installed as .tsx files; otherwise, .jsx is used.
  • iconLibrary: String specifying the default icon set, such as "lucide" or "radix".

Tailwind Configuration

The tailwind object contains critical paths and styling options:

  • config: Path to the Tailwind configuration file (e.g., "tailwind.config.ts" or "" for Tailwind v4).
  • css: Path to the global CSS file where Tailwind directives are defined (e.g., "src/app/globals.css").
  • baseColor: The neutral color scale used as the base (e.g., "neutral", "zinc", "slate").
  • cssVariables: Boolean indicating whether to use CSS variables for theming.
  • prefix (optional): Custom prefix for Tailwind classes (e.g., "tw-") to avoid CSS conflicts.

Path Aliases

The aliases object maps import aliases to their actual paths, enabling the CLI to resolve component locations:

  • components: Base path for components (e.g., "@/components").
  • utils: Path to utility functions, typically containing the cn() helper (e.g., "@/lib/utils").
  • ui: Specific path for shadcn-ui components (e.g., "@/components/ui").
  • lib: General library path (e.g., "@/lib").
  • hooks: Path for custom React hooks (e.g., "@/hooks").

Custom Registries

The optional registries object allows you to define user-defined component registries or override built-in ones. Each registry key must start with @ and can be either:

  • A string URL template containing a {name} placeholder.
  • An object with url (required), optional params, and optional headers for authentication.

How the CLI Uses components.json

The shadcn-ui CLI relies on several utility modules to interact with the components.json configuration file. Understanding these internals helps debug configuration issues.

In packages/shadcn/src/utils/get-config.ts, the getConfig function implements a hierarchical file discovery mechanism. It searches upward from the current working directory until it finds a components.json file, ensuring monorepo sub-packages can inherit configuration from root levels.

Once found, the configuration undergoes strict validation against the JSON-Schema defined in deprecated/www/public/schema.json. If validation fails, the CLI emits helpful errors via packages/shadcn/src/registry/errors.ts, providing specific feedback about missing required fields or invalid alias paths.

For file system operations, packages/shadcn/src/registry/utils.ts provides utilities to read and update the configuration file atomically. This ensures that commands like shadcn add can safely modify aliases or registry entries without corrupting the JSON structure.

Practical Configuration Examples

Real-world usage of the components.json configuration file in shadcn-ui varies from minimal setups to complex monorepo configurations.

Minimal Setup for a Next.js Project

The following example from the official monorepo template demonstrates a standard configuration for a TypeScript Next.js project using React Server Components:

{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "default",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "",
    "css": "src/styles/globals.css",
    "baseColor": "neutral",
    "cssVariables": true
  },
  "iconLibrary": "lucide",
  "aliases": {
    "components": "@workspace/ui/components",
    "utils": "@workspace/ui/lib/utils",
    "hooks": "@workspace/ui/hooks",
    "lib": "@workspace/ui/lib",
    "ui": "@workspace/ui/components"
  }
}

Source: [templates/monorepo-next/packages/ui/components.json](https://github.com/shadcn-ui/ui/blob/main/templates/monorepo-next/packages/ui/components.json)

Adding a Custom Component Registry

To integrate a private component library or third-party registry, extend the configuration with the registries field:

{
  "style": "default",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.ts",
    "css": "src/app/globals.css",
    "baseColor": "zinc",
    "cssVariables": true
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils"
  },
  "registries": {
    "@my-company/ui": {
      "url": "https://registry.my-company.com/{name}",
      "params": { "token": "YOUR_API_TOKEN" },
      "headers": { "Authorization": "Bearer abc123" }
    }
  }
}

The CLI will now resolve imports that start with @my-company/ui/ using the supplied endpoint, substituting {name} with the specific component name.

Configuring Tailwind Prefixes

For projects requiring Tailwind class prefixes to avoid conflicts with other CSS frameworks, use the optional prefix field:

{
  "style": "new-york",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.ts",
    "css": "src/app/globals.css",
    "baseColor": "zinc",
    "cssVariables": true,
    "prefix": "tw-"
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils"
  }
}

Source: [packages/shadcn/test/fixtures/config-full/components.json](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/test/fixtures/config-full/components.json)

Summary

  • The components.json configuration file in shadcn-ui acts as the single source of truth for the CLI, enabling automated component installation, updates, and migration across diverse project structures.
  • The CLI discovers the file by searching upward from the current directory using the hierarchical discovery logic in packages/shadcn/src/utils/get-config.ts.
  • All configurations undergo strict validation against the JSON-Schema defined in deprecated/www/public/schema.json to prevent runtime errors.
  • Required fields include style, tailwind (with config, css, baseColor, cssVariables), rsc, and aliases, while registries and Tailwind prefix remain optional.
  • The file supports custom component registries through the registries field, allowing integration of private or third-party component libraries with custom authentication headers.

Frequently Asked Questions

What happens if the components.json file is missing or malformed?

If the CLI cannot locate components.json or if the file fails JSON-Schema validation, the command exits with a descriptive error. The error handling logic in packages/shadcn/src/registry/errors.ts provides specific feedback about missing required fields, invalid alias paths, or type mismatches, guiding you to correct the configuration before retrying the command.

Can I use components.json in a JavaScript project without TypeScript?

Yes. Set the tsx field to false in your configuration. When tsx is false, the CLI installs components as .jsx files instead of .tsx and adjusts import statements accordingly. The rsc field operates independently, allowing you to use React Server Components regardless of whether your project uses TypeScript or JavaScript.

How do custom registries work in components.json?

The registries field allows you to define custom namespaces that resolve to external component sources. Each registry key must start with @ and can specify a URL template containing a {name} placeholder. When you run shadcn add @my-company/ui/button, the CLI substitutes button into the URL template, fetches the component definition, and installs it using your project's configured aliases and Tailwind settings.

Where does the CLI search for components.json?

The CLI implements an upward directory traversal algorithm starting from the current working directory. Defined in packages/shadcn/src/utils/get-config.ts, this search continues through parent directories until it finds a components.json file or reaches the filesystem root. This approach supports monorepo architectures where sub-packages can inherit configuration from the repository root, allowing consistent component management across multiple applications within a single codebase.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →