# How to Configure Component Aliases and Custom Output Paths for shadcn Components

> Learn how to configure shadcn component aliases and custom output paths easily. Enhance your project setup with clear instructions and efficient customization options.

- Repository: [shadcn-ui/ui](https://github.com/shadcn-ui/ui)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Configure component aliases by editing the `aliases` object in [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) or via interactive prompts during `shadcn init`, and set custom output paths using the `-o` flag with `shadcn registry:build` or `shadcn build`.**

The `shadcn-ui/ui` repository uses a centralized configuration system driven by [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) to manage how components are imported and where generated files are stored. This configuration file controls the scaffolding pipeline, allowing you to customize import aliases for different module categories and specify custom directories for registry build outputs.

## Understanding the components.json Configuration File

The [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) file serves as the single source of truth for the shadcn CLI. Located at the root of your project (or package root in monorepos), it defines style preferences, TypeScript settings, Tailwind configuration, and critically, the **alias map** that the CLI uses to resolve imports.

### Alias Configuration Structure

Aliases are defined under the `aliases` key as path mappings. According to the source code in [`packages/shadcn/src/utils/get-config.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/utils/get-config.ts) (lines 75-89), the configuration loader validates and resolves these aliases using TypeScript path-mapping resolution. The system supports five distinct alias categories:

- `components` – Base path for UI components
- `utils` – Utility functions (typically `cn` helpers)
- `lib` – Shared library code
- `hooks` – Custom React hooks
- `ui` – Specific UI component directory (often mirrors `components`)

## Configuring Import Aliases in shadcn

You can configure aliases either interactively during project initialization or by manually editing [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) after setup.

### Interactive Setup During Initialization

When running `npx shadcn@latest init`, the CLI prompts for alias configuration. As implemented in [`packages/shadcn/src/commands/init.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/commands/init.ts) (lines 84-94), the interactive flow asks for:

1. The import alias for components (e.g., `@/components`)
2. The import alias for utility functions (e.g., `@/lib/utils`)

These values are written directly to [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) under the `aliases` object.

### Manual Configuration in components.json

For advanced setups, particularly in monorepos, manual configuration provides finer control. The template at [`templates/monorepo-next/packages/ui/components.json`](https://github.com/shadcn-ui/ui/blob/main/templates/monorepo-next/packages/ui/components.json) (lines 13-19) demonstrates a typical monorepo alias structure:

```json
{
  "aliases": {
    "components": "@myorg/ui/src/components",
    "utils": "@myorg/ui/src/lib/utils",
    "hooks": "@myorg/ui/src/hooks",
    "lib": "@myorg/ui/src/lib",
    "ui": "@myorg/ui/src/components"
  }
}

```

After editing [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json), subsequent `shadcn add` commands automatically resolve imports using the new alias mappings via the [`transform-import.ts`](https://github.com/shadcn-ui/ui/blob/main/transform-import.ts) transformer.

## Setting Custom Output Paths for Registry Builds

When building a custom component registry, you can specify where the generated JSON artifacts are written using the `--output` (or `-o`) flag.

### Using the --output Flag

Both the standard build command and the registry-specific build command support custom output directories. As defined in [`packages/shadcn/src/commands/registry/build.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/commands/registry/build.ts) (lines 15-31) and mirrored in [`packages/shadcn/src/commands/build.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/commands/build.ts) (lines 15-31), the CLI accepts:

```bash

# Build registry to default ./public/r

shadcn registry:build

# Build registry to custom directory

shadcn registry:build -o ./dist/custom-registry
shadcn registry:build --output ./public/my-components

```

The same flag works for the experimental `build` command:

```bash
shadcn build -o ./output

```

### How Output Directory Resolution Works

The CLI handles path resolution and directory creation automatically. In [`packages/shadcn/src/preflights/preflight-build.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/preflights/preflight-build.ts) (lines 17-18), the preflight step resolves the provided path relative to the current working directory and ensures the directory exists:

```typescript
// Conceptual flow from preflight-build.ts
const outputDir = path.resolve(cwd, options.output);
await fs.mkdir(outputDir, { recursive: true });

```

This ensures that custom output paths are created recursively if they don't exist, preventing errors during the file write operations that follow in the build logic.

## Key Implementation Details from Source Code

The alias system relies on several key utilities in the shadcn codebase:

- **[`packages/shadcn/src/utils/get-config.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/utils/get-config.ts)** (lines 75-89): Validates and loads [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json), resolving alias paths using TypeScript's path mapping resolution.
- **[`packages/shadcn/src/utils/transform-import.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/utils/transform-import.ts)**: Rewrites import statements in generated components to match the configured aliases from [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json).
- **[`packages/shadcn/src/preflights/preflight-registry.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/preflights/preflight-registry.ts)** (lines 18-42): Handles output directory validation and creation for registry builds, similar to the standard build preflight.

## Summary

- **Component aliases** are configured in [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) under the `aliases` key, supporting `components`, `utils`, `lib`, `hooks`, and `ui` mappings.
- **Interactive configuration** is available during `shadcn init` via prompts defined in [`packages/shadcn/src/commands/init.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/commands/init.ts).
- **Custom output paths** for registry builds use the `-o` or `--output` flag with `shadcn registry:build` or `shadcn build`.
- The CLI automatically creates missing output directories via preflight checks in [`preflight-build.ts`](https://github.com/shadcn-ui/ui/blob/main/preflight-build.ts) and [`preflight-registry.ts`](https://github.com/shadcn-ui/ui/blob/main/preflight-registry.ts).

## Frequently Asked Questions

### What are the default alias keys supported by shadcn?

The [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) alias configuration supports five specific keys: `components` (base component directory), `utils` (utility functions like `cn`), `lib` (shared library code), `hooks` (custom React hooks), and `ui` (UI-specific components). These are validated and resolved by the configuration loader in [`packages/shadcn/src/utils/get-config.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/utils/get-config.ts).

### Can I change aliases after initializing a project?

Yes, you can modify aliases at any time by editing the `aliases` object in your [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) file. After making changes, subsequent `shadcn add` commands will automatically use the updated paths when generating imports, as the CLI re-reads the configuration on each execution via [`get-config.ts`](https://github.com/shadcn-ui/ui/blob/main/get-config.ts).

### How do I configure aliases for a monorepo setup?

For monorepos, specify package-scoped aliases in your [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) using your workspace's import conventions. For example, set `"components": "@myorg/ui/src/components"` and `"utils": "@myorg/ui/src/lib/utils"` to map imports to your shared UI package. The template at [`templates/monorepo-next/packages/ui/components.json`](https://github.com/shadcn-ui/ui/blob/main/templates/monorepo-next/packages/ui/components.json) demonstrates this pattern for Next.js monorepos.

### What happens if the custom output directory doesn't exist?

The CLI automatically creates the specified output directory if it doesn't exist. During the preflight phase of both `shadcn build` and `shadcn registry:build`, the code in [`packages/shadcn/src/preflights/preflight-build.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/preflights/preflight-build.ts) (lines 17-18) executes `fs.mkdir(outputDir, { recursive: true })`, ensuring the full path is created recursively before any files are written.