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/*"] } } } ```