Skip to content

Shadcn components.json Explained: Every Field, What It Does

Written By Ajay Patel Categories: tutorials
Published: Updated:
11 min read

Shadcn components.json Explained: Every Field, What It Does

If you are working with shadcn/ui, there is probably a components.json file in your project root. It appears when you initialize shadcn/ui with the CLI, and its small size makes it easy to overlook.

That file controls more than you might expect: where components are installed, how imports are written, which design style and base color your project uses, whether the CLI generates .tsx or .jsx files, and which additional registries it can access.

In this guide, we will break down every field in components.json, explain which settings you are likely to change, and point out the options that should remain consistent after initialization.

What Is components.json in a Shadcn Project?

The components.json file stores the shadcn/ui CLI configuration for your project. The CLI reads it to understand your framework setup and generate components that match your project.

You can create the file by running:

npx shadcn@latest init

The file is optional if you manually copy and paste component code. It is required when you use the CLI to add shadcn/ui components.

Note: The correct filename is components.json, with an s. It is not component.json.

A Complete components.json Example

Here is a modern components.json example for a TypeScript project using Tailwind CSS v4:

{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "base-nova",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "",
    "css": "app/globals.css",
    "baseColor": "neutral",
    "cssVariables": true,
    "prefix": ""
  },
  "iconLibrary": "lucide",
  "rtl": false,
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils",
    "ui": "@/components/ui",
    "lib": "@/lib",
    "hooks": "@/hooks"
  },
  "menuColor": "default",
  "menuAccent": "subtle",
  "registries": {}
}

Your file may contain fewer fields or different values depending on when it was created, which framework you use, and which options you selected during initialization.

components.json Field Reference

FieldWhat it controlsExample value
$schemaEditor autocomplete and validationhttps://ui.shadcn.com/schema.json
styleComponent style and primitive basebase-nova
rscReact Server Component supporttrue
tsxTypeScript or JavaScript outputtrue
tailwind.configTailwind config file path"" for Tailwind v4
tailwind.cssGlobal CSS file used by the projectapp/globals.css
tailwind.baseColorBase palette for generated theme tokensneutral
tailwind.cssVariablesCSS variables or inline color utilitiestrue
tailwind.prefixPrefix applied to Tailwind classes""
iconLibraryIcon package used by generated componentslucide
rtlRight-to-left component generationfalse
aliasesInstall locations and generated import paths@/components
menuColorMenu color treatment for the selected design systemdefault
menuAccentMenu highlight treatmentsubtle
registriesAdditional component registry sources{}

Every components.json Field Explained

Let’s examine each field in detail so you can understand how it affects the shadcn/ui CLI, generated components, and your project’s configuration.

$schema

The $schema field points to the official JSON Schema for components.json.

{
  "$schema": "https://ui.shadcn.com/schema.json"
}

It gives supported editors autocomplete, documentation hints, and validation. It does not change the generated UI, but keeping it in the file makes configuration mistakes easier to catch.

style

The style field identifies the component style used by the project.

{
  "style": "base-nova"
}

Modern style values combine a primitive base with a visual style. For example, base-nova uses Base UI primitives with the Nova design style, while radix-vega uses Radix UI primitives with Vega.

The current schema includes these visual style families:

  • Vega
  • Nova
  • Maia
  • Lyra
  • Mira
  • Luma
  • Sera
  • Rhea

Each preset has its own spacing, border-radius, and shadow choices, so you can select the visual direction that best fits your interface.

If your team chooses styles in design before generating code, the Shadcn Figma UI Kit can help compare the visual system in Figma, while the Figma plugin provides a path from an approved design back to implementation.

The older default style is deprecated. Legacy projects may still use new-york, but new projects should use one of the current style options offered by shadcn/create.

The official documentation treats style as an initialization-time choice. Changing it later can cause newly installed components to follow a different implementation or design convention than the components already in your repository.

rsc

The rsc field enables React Server Component support.

{
  "rsc": true
}

When it is true, the CLI adds the "use client" directive to generated components that require client-side React features. Set it to false for projects that do not use React Server Components, such as many Vite applications.

This option affects components generated after the change. It does not rewrite components that are already installed.

tsx

The tsx field determines whether the CLI generates TypeScript or JavaScript components.

{
  "tsx": true
}
  • true generates .tsx files.
  • false generates .jsx files.

Changing this setting does not convert existing files. It only changes what the CLI generates next.

tailwind

The tailwind object tells the CLI how Tailwind CSS is configured in your project.

{
  "tailwind": {
    "config": "",
    "css": "app/globals.css",
    "baseColor": "neutral",
    "cssVariables": true,
    "prefix": ""
  }
}

It contains five settings: config, css, baseColor, cssVariables, and prefix.

tailwind.config

This field points to the Tailwind configuration file.

{
  "tailwind": {
    "config": ""
  }
}

For Tailwind CSS v4, leave it blank because configuration moved into CSS. A Tailwind CSS v3 project can instead reference tailwind.config.js or tailwind.config.ts.

tailwind.css

This is the path to the CSS file that imports Tailwind CSS and contains your theme variables.

{
  "tailwind": {
    "css": "app/globals.css"
  }
}

The correct path depends on your framework and project structure. A Next.js project may use app/globals.css or src/app/globals.css, while a Vite project may use src/index.css.

If you move the file, update this path before using the CLI again. An incorrect value can prevent shadcn/ui from finding or updating the stylesheet it expects.

tailwind.baseColor

The baseColor field selects the neutral palette used to generate the project’s default theme tokens.

{
  "tailwind": {
    "baseColor": "neutral"
  }
}

Supported values include:

  • neutral
  • stone
  • zinc
  • mauve
  • olive
  • mist
  • taupe

This is an initialization-time setting. Editing the value later does not regenerate the CSS variables already written to your stylesheet. To change the appearance of an existing project, update its theme tokens instead of relying on this field alone.

For a visual way to experiment before editing those tokens, the Shadcn Theme Generator lets you preview a palette and then apply the resulting CSS variables to the project.

tailwind.cssVariables

This setting controls whether generated components use semantic CSS variables or inline color utilities.

With cssVariables set to true, components use semantic tokens:

<div className="bg-primary text-primary-foreground">Hello</div>

With it set to false, components can use direct color utilities:

<div className="bg-zinc-950 text-zinc-50 dark:bg-white dark:text-zinc-950">
  Hello
</div>

The shadcn/ui documentation recommends CSS variables because they let you update shared theme tokens in one place. This choice cannot be switched cleanly after initialization without deleting and reinstalling the affected components.

tailwind.prefix

The prefix field adds a prefix to Tailwind utility classes generated by the CLI.

{
  "tailwind": {
    "prefix": "tw-"
  }
}

For example, a utility such as flex would follow your prefixed Tailwind convention. Leave the value empty when your project does not use a prefix.

If you introduce or change a prefix later, remember that the setting does not update existing component files automatically.

aliases

The aliases object tells the CLI where to install files and which import paths to write.

{
  "aliases": {
    "components": "@/components",
    "ui": "@/components/ui",
    "utils": "@/lib/utils",
    "lib": "@/lib",
    "hooks": "@/hooks"
  }
}

Each alias has a distinct purpose:

AliasUsed for
componentsShared application components
uishadcn/ui component installation directory
utilsUtility imports such as the cn helper
libGeneral library functions
hooksReusable React hooks

The ui alias is the setting developers customize most often. For example, setting it to @/app/ui tells the CLI to install UI components in that location.

These aliases must match a real path-resolution configuration. A common tsconfig.json setup is:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

The CLI also supports package.json#imports:

{
  "imports": {
    "#components/*": "./src/components/*.tsx",
    "#lib/*": "./src/lib/*.ts",
    "#hooks/*": "./src/hooks/*.ts"
  }
}

When using package imports, enable the matching TypeScript options:

{
  "compilerOptions": {
    "moduleResolution": "bundler",
    "resolvePackageJsonImports": true
  }
}

If components.json and your TypeScript or package configuration disagree, the CLI may generate imports that your editor and bundler cannot resolve.

iconLibrary

The iconLibrary field tells the CLI which icon package generated components should use.

{
  "iconLibrary": "lucide"
}

Common choices offered by the shadcn/ui setup flow include Lucide, Hugeicons, Tabler Icons, Phosphor Icons, and Remix Icons.

Choose this setting during initialization and keep it consistent. Changing the value does not update icon imports in files you already own, so future components could use a different icon package unless you migrate the existing imports yourself.

rtl

The rtl field controls right-to-left support in generated components.

{
  "rtl": true
}

Enable it for interfaces built for right-to-left languages such as Arabic, Hebrew, or Persian. Direction-aware styles and component behavior can then be generated with RTL support in mind.

For an existing project, use the migration command instead of only editing the boolean:

npx shadcn@latest migrate rtl

You can optionally pass a path to limit the migration scope.

The menuColor field stores the menu color treatment selected for the design system.

{
  "menuColor": "default"
}

The current schema accepts:

  • default
  • inverted
  • default-translucent
  • inverted-translucent

The inverted variants create stronger contrast against the page, while the translucent variants produce a layered appearance.

The menuAccent field controls the visual strength of highlighted menu items.

{
  "menuAccent": "subtle"
}

It accepts subtle or bold. Use subtle for a quieter treatment and bold for a more prominent active or highlighted state.

Like the other generation settings, changing it does not restyle component source files that are already installed.

registries

One of the most useful fields, and the one many developers never touch, is registries. It lets the CLI install components, blocks, pages, themes, and other resources from sources beyond the default shadcn/ui registry.

For example, you can configure the Shadcn Studio registries like this:

{
  "registries": {
    "@shadcn-studio": "https://shadcnstudio.com/r/{style}/{name}.json",
    "@ss-components": "https://shadcnstudio.com/r/components/{style}/{name}.json",
    "@ss-blocks": "https://shadcnstudio.com/r/blocks/{style}/{name}.json",
    "@ss-pages": "https://shadcnstudio.com/r/pages/{style}/{name}.json",
    "@ss-themes": "https://shadcnstudio.com/r/themes/{name}.json"
  }
}

Two placeholders are replaced at install time. {name} becomes the resource you are installing, while {style} becomes your project’s configured style preset.

Before choosing a registry item, you can inspect individual Shadcn Components or compare complete Shadcn Blocks, then use the corresponding registry name with the CLI.

npx shadcn@latest add @shadcn-studio/button-01

Advanced Configuration with Authentication

Private registries can include authentication headers, with environment variables expanded automatically:

{
  "registries": {
    "@private": {
      "url": "https://api.company.com/registry/{name}.json",
      "headers": {
        "Authorization": "Bearer ${REGISTRY_TOKEN}"
      }
    }
  }
}

The same approach works with query parameters, which licensed registries can use to verify access:

{
  "registries": {
    "@shadcn-studio": "https://shadcnstudio.com/r/{style}/{name}.json",
    "@ss-blocks": {
      "url": "https://shadcnstudio.com/r/blocks/{style}/{name}.json",
      "params": {
        "email": "${EMAIL}",
        "license_key": "${LICENSE_KEY}"
      }
    }
  }
}

Environment variables in the ${VAR_NAME} format are expanded automatically. Keep secrets in your environment file or deployment platform, not directly in components.json.

This setup also gives teams a way to share an internal component library without publishing an npm package.

Using Namespaced Registries

Once configured, install Shadcn Studio resources using the namespace syntax:

Install from a configured registry:

npx shadcn@latest add @shadcn-studio/button-01

Install a premium component:

npx shadcn@latest add @ss-components/premium-component-name

Install multiple resources at once:

npx shadcn@latest add @ss-components/button-01 @shadcn-studio/hero-section-01

Namespaced registries are not limited to individual UI pieces. They can also distribute complete Shadcn Pages and project-level Shadcn Templates while preserving the same source-code ownership model.

If you prefer exploring registry resources from your editor, the Shadcn Studio MCP server connects the same ecosystem to supported IDEs and AI development tools.

Which Fields Can You Change Later?

The important distinction is not simply whether JSON can be edited. You can edit any text in the file, but some changes are unsupported or leave existing source files out of sync.

FieldGuidance after initialization
$schemaSafe to update
styleDo not change; it is an initialization-time choice
tailwind.baseColorDo not rely on changing it; edit existing theme tokens instead
tailwind.cssVariablesRequires deleting and reinstalling affected components
tailwind.configUpdate if the real config path changes
tailwind.cssUpdate if the global stylesheet moves
tailwind.prefixCan change generation, but does not rewrite existing classes
rscAffects components generated afterward
tsxAffects components generated afterward
aliasesCan be changed, but move existing files and update imports too
iconLibraryKeep consistent unless you also migrate existing icon imports
rtlUse the CLI migration for an existing project
menuColorDoes not rewrite existing components
menuAccentDoes not rewrite existing components
registriesAdd or remove registry sources as needed

The key rule is simple: editing components.json never rewrites the component files already in your repository. The file primarily tells the CLI how to handle future operations.

Common components.json Mistakes

  • Adding a Tailwind Config Path in a v4 Project: Leave tailwind.config blank when you use Tailwind CSS v4. Do not point it to a JavaScript configuration file that does not exist.

  • Using Aliases That Do Not Match tsconfig.json: The CLI writes imports based on components.json, but TypeScript and your bundler resolve them using tsconfig.json, jsconfig.json, or package.json#imports. If those configurations disagree, imports break.

  • Using a baseColor That Does Not Exist: Use one of the seven supported values listed above. An unsupported value will fail schema validation or initialization.

  • Expecting baseColor to Retheme an Existing App: The value helps generate the initial theme tokens. Changing it later does not replace the variables already present in your CSS. Edit the theme in your global stylesheet instead.

  • Changing the Icon Library Without Migrating Imports: Installed components remain ordinary source files and keep their existing imports. Switching the configuration can leave your project using multiple icon libraries.

  • Putting Secrets Directly in Registry Configuration: Use environment-variable placeholders for private registry credentials. Never commit real API keys, tokens, or license keys to components.json.

  • Assuming the CLI Updates Existing Components: Most configuration changes only affect future CLI operations. Review and migrate existing component files when changing paths, language, icon, prefix, or direction conventions.

Key Takeaways

  • components.json configures the shadcn/ui CLI; it is not required for manual copy-and-paste usage.
  • style, baseColor, and cssVariables should be treated as initialization-time decisions.
  • Tailwind CSS v4 projects should leave tailwind.config blank.
  • Aliases must match your TypeScript, JavaScript, or package import configuration.
  • Changing a field does not automatically update components already in your repository.
  • Existing projects should use the RTL migration command rather than only changing rtl.
  • The registries field can connect a project to public, private, or internal component sources.pages

Conclusion

components.json is a small file, but it quietly defines how the shadcn/ui CLI interacts with your project. It controls where components are installed, how imports are generated, which styling conventions they follow, and where additional resources can come from.

Read the file before changing it, and remember that shadcn/ui components become source code you own as soon as they are installed. Configuration changes guide future CLI operations; they do not retroactively rewrite that code.

Understanding that distinction will help you avoid broken aliases, mixed icon libraries, misplaced files, and confusing theme behavior as your project grows.