export const title = "components.json";
export const description = "The components.json file is an optional configuration file for the Untitled UI CLI. Use it to customize import aliases and paths for your project structure.";
## Overview
The `components.json` file allows you to configure how the CLI handles import paths and file locations when adding components to your project. This is particularly useful for:
- **Monorepos** with custom workspace aliases
- **Projects** with non-standard directory structures
- **Teams** that want consistent component installation paths
**Note:** The `components.json` file is **optional**. If you don't have one, the CLI will auto-detect your project structure from `tsconfig.json` and prompt you for paths as needed.
## Creating components.json
Create a `components.json` file in the root of your project (or the folder where you run the CLI):
```json
{
"aliases": {
"components": "@/components/",
"utils": "@/utils/",
"hooks": "@/hooks/",
"styles": "@/styles/"
},
"examples": "app"
}
```
## Configuration options
### aliases
The `aliases` object defines the import path prefixes used in your component files. These **must match your tsconfig.json path mappings**.
```json
{
"aliases": {
"components": "@/components/",
"utils": "@/utils/",
"hooks": "@/hooks/",
"styles": "@/styles/"
}
}
```
| Property | Description |
|----------|-------------|
| `components` | Import alias for component files (e.g., `@/components/`, `@workspace/ui/components/`) |
| `utils` | Import alias for utility functions (e.g., `@/utils/`, `~/lib/utils/`) |
| `hooks` | Import alias for React hooks (e.g., `@/hooks/`) |
| `styles` | Import alias for style files (e.g., `@/styles/`) |
| `app` | Import alias for `@/app/` imports (e.g., `@workspace/web/app/`) |
| `src` | Fallback alias for any other `@/` import that none of the keys above cover (e.g., `~/`) |
**Important:** Aliases must be valid tsconfig path aliases, not relative paths. The CLI uses your `tsconfig.json` to resolve these aliases to actual filesystem locations.
### examples
The `examples` property specifies where example page files should be installed. This is useful when working in a monorepo where your web app is in a different directory.
```json
{
"examples": "../../apps/web"
}
```
### version
The `version` property pins the component library version the CLI pulls (`"7"` or `"8"`). It is optional and defaults to `"8"`. The `upgrade` command sets it to `"8"` when a migration completes. See [Version support](/docs/cli#version-support).
```json
{
"version": "7"
}
```
The CLI reads only `aliases`, `examples` and `version`; any other keys are ignored.
## How aliases work
When you add a component, the CLI performs two key operations using your aliases:
### 1. Import statement transformation
The CLI rewrites import statements in component code to match your aliases:
```tsx
// Original component code
import { Button } from "@/components/base/buttons/button";
import { cx } from "@/utils/cx";
// After transformation (if your alias is @workspace/ui/)
import { Button } from "@workspace/ui/components/base/buttons/button";
import { cx } from "@workspace/ui/utils/cx";
```
### 2. File path resolution
The CLI uses your `tsconfig.json` paths to determine where to place files on disk:
```json
// tsconfig.json
{
"compilerOptions": {
"paths": {
"@workspace/ui/*": ["./packages/ui/src/*"]
}
}
}
```
With the above config, a component with path `components/base/button.tsx` would be installed to `./packages/ui/src/components/base/button.tsx`.
## Alias requirements
**Critical:** Aliases in `components.json` must be valid tsconfig path aliases. Relative paths like `../../components` will **not work correctly**.
### Why relative paths don't work
The CLI uses the `tsconfig-paths` library to resolve aliases to filesystem locations. This library only understands aliases defined in your `tsconfig.json` paths configuration.
| Alias Format | Works? | Reason |
|--------------|--------|--------|
| `@/components/` | Yes | Resolved via tsconfig paths |
| `@workspace/ui/` | Yes | Resolved via tsconfig paths |
| `~/components/` | Yes | Resolved via tsconfig paths |
| `../../components/` | No | Cannot be resolved by tsconfig-paths |
| `/absolute/path/` | No | Cannot be resolved by tsconfig-paths |
### Correct setup
To use custom aliases, you must configure **both** your `tsconfig.json` and `components.json`:
Add your path mappings to `tsconfig.json`:
```json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@workspace/ui/*": ["./packages/ui/src/*"]
}
}
}
```
Reference the same aliases in `components.json`:
```json
{
"aliases": {
"components": "@workspace/ui/components/",
"utils": "@workspace/ui/utils/",
"hooks": "@workspace/ui/hooks/",
"styles": "@workspace/ui/styles/"
}
}
```
Now the CLI will correctly resolve paths and transform imports:
```bash
npx untitledui@latest add button
```
## Example configurations
### Standard Next.js project
```json
{
"aliases": {
"components": "@/components/",
"utils": "@/utils/",
"hooks": "@/hooks/",
"styles": "@/styles/"
}
}
```
With corresponding `tsconfig.json`:
```json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
```
### Monorepo with shared UI package
```json
{
"aliases": {
"components": "@workspace/ui/components/",
"utils": "@workspace/ui/utils/",
"hooks": "@workspace/ui/hooks/",
"styles": "@workspace/ui/styles/"
},
"examples": "../../apps/web"
}
```
With corresponding `tsconfig.json`:
```json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@workspace/ui/*": ["./packages/ui/src/*"]
}
}
}
```
### Vite project with custom alias
```json
{
"aliases": {
"components": "~/components/",
"utils": "~/lib/",
"hooks": "~/hooks/",
"styles": "~/styles/"
}
}
```
With corresponding `tsconfig.json`:
```json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~/*": ["./src/*"]
}
}
}
```