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:
pnpm dlx shadcn@latest init npx shadcn@latest init yarn dlx shadcn@latest init bunx --bun 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 notcomponent.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
| Field | What it controls | Example value |
|---|---|---|
$schema | Editor autocomplete and validation | https://ui.shadcn.com/schema.json |
style | Component style and primitive base | base-nova |
rsc | React Server Component support | true |
tsx | TypeScript or JavaScript output | true |
tailwind.config | Tailwind config file path | "" for Tailwind v4 |
tailwind.css | Global CSS file used by the project | app/globals.css |
tailwind.baseColor | Base palette for generated theme tokens | neutral |
tailwind.cssVariables | CSS variables or inline color utilities | true |
tailwind.prefix | Prefix applied to Tailwind classes | "" |
iconLibrary | Icon package used by generated components | lucide |
rtl | Right-to-left component generation | false |
aliases | Install locations and generated import paths | @/components |
menuColor | Menu color treatment for the selected design system | default |
menuAccent | Menu highlight treatment | subtle |
registries | Additional 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
}
truegenerates.tsxfiles.falsegenerates.jsxfiles.
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:
neutralstonezincmauveolivemisttaupe
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:
| Alias | Used for |
|---|---|
components | Shared application components |
ui | shadcn/ui component installation directory |
utils | Utility imports such as the cn helper |
lib | General library functions |
hooks | Reusable 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:
pnpm dlx shadcn@latest migrate rtl npx shadcn@latest migrate rtl yarn dlx shadcn@latest migrate rtl bunx --bun shadcn@latest migrate rtl You can optionally pass a path to limit the migration scope.
menuColor
The menuColor field stores the menu color treatment selected for the design system.
{
"menuColor": "default"
}
The current schema accepts:
defaultinverteddefault-translucentinverted-translucent
The inverted variants create stronger contrast against the page, while the translucent variants produce a layered appearance.
menuAccent
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.
pnpm dlx shadcn@latest add @shadcn-studio/button-01 npx shadcn@latest add @shadcn-studio/button-01 yarn dlx shadcn@latest add @shadcn-studio/button-01 bunx --bun 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:
pnpm dlx shadcn@latest add @shadcn-studio/button-01 npx shadcn@latest add @shadcn-studio/button-01 yarn dlx shadcn@latest add @shadcn-studio/button-01 bunx --bun shadcn@latest add @shadcn-studio/button-01 Install a premium component:
pnpm dlx shadcn@latest add @ss-components/premium-component-name npx shadcn@latest add @ss-components/premium-component-name yarn dlx shadcn@latest add @ss-components/premium-component-name bunx --bun shadcn@latest add @ss-components/premium-component-name Install multiple resources at once:
pnpm dlx shadcn@latest add @ss-components/button-01 @shadcn-studio/hero-section-01 npx shadcn@latest add @ss-components/button-01 @shadcn-studio/hero-section-01 yarn dlx shadcn@latest add @ss-components/button-01 @shadcn-studio/hero-section-01 bunx --bun 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.
| Field | Guidance after initialization |
|---|---|
$schema | Safe to update |
style | Do not change; it is an initialization-time choice |
tailwind.baseColor | Do not rely on changing it; edit existing theme tokens instead |
tailwind.cssVariables | Requires deleting and reinstalling affected components |
tailwind.config | Update if the real config path changes |
tailwind.css | Update if the global stylesheet moves |
tailwind.prefix | Can change generation, but does not rewrite existing classes |
rsc | Affects components generated afterward |
tsx | Affects components generated afterward |
aliases | Can be changed, but move existing files and update imports too |
iconLibrary | Keep consistent unless you also migrate existing icon imports |
rtl | Use the CLI migration for an existing project |
menuColor | Does not rewrite existing components |
menuAccent | Does not rewrite existing components |
registries | Add 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.configblank 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 oncomponents.json, but TypeScript and your bundler resolve them usingtsconfig.json,jsconfig.json, orpackage.json#imports. If those configurations disagree, imports break. -
Using a
baseColorThat Does Not Exist: Use one of the seven supported values listed above. An unsupported value will fail schema validation or initialization. -
Expecting
baseColorto 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.jsonconfigures the shadcn/ui CLI; it is not required for manual copy-and-paste usage.style,baseColor, andcssVariablesshould be treated as initialization-time decisions.- Tailwind CSS v4 projects should leave
tailwind.configblank. - 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
registriesfield 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.