# How to Configure Multiple Registries in shadcn/ui to Pull Components from Different Sources

> Learn how to configure multiple registries in shadcn ui to pull components from various sources. Easily add third-party components and private APIs using your components.json file.

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

---

**You can configure multiple registries in shadcn/ui by adding entries to the `registries` field in your [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) file, allowing you to pull components from third-party sources, private APIs, and custom namespaces using the standard `npx shadcn add` command.**

The shadcn/ui CLI supports a **namespaced registry system** that consolidates component sources from any HTTP-accessible endpoint into a single configuration. According to the shadcn-ui/ui source code, this architecture enables teams to distribute internal component libraries alongside the official registry without altering installation workflows. By declaring custom registries in [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json), you can execute `npx shadcn add @namespace/component` to pull from private repos, third-party design systems, or organization-specific APIs.

## Understanding the Registry Architecture

Shadcn/ui implements a tiered registry system that separates built-in sources from user-defined configurations. This design ensures that the official registry remains accessible while allowing unlimited extension through custom namespaces.

### Built-in Registry Protection

The CLI maintains the official shadcn registry as a protected constant. In [`packages/shadcn/src/registry/constants.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/registry/constants.ts) (lines 32-35), the `BUILTIN_REGISTRIES` constant defines `@shadcn` as an immutable entry pointing to `https://ui.shadcn.com/r/styles/{style}/{name}.json`. This implementation prevents accidental overrides of the core registry, ensuring that standard components like `button` or `input` always resolve to the official source even when you configure multiple registries.

### Configuration Merging Logic

When the CLI loads a project, the `getConfig` utility in [`packages/shadcn/src/utils/get-config.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/utils/get-config.ts) (lines 50-55) merges the built-in registries with your custom entries. This merge produces a unified `config.registries` map that the CLI consults for every component lookup. The process preserves the built-in definitions while appending your custom namespaces, creating a single source of truth for resolving `@namespace/component` syntax.

## Setting Up Multiple Registries in components.json

The [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) file accepts a `registries` key that accepts both simple URL strings and advanced configuration objects. According to the documentation in `apps/v4/content/docs/registry/namespace.mdx` (lines 48-63), each registry entry maps a namespace to its endpoint pattern.

Here is a complete configuration demonstrating multiple registry types:

```json
{
  "registries": {
    "@shadcn": "https://ui.shadcn.com/r/styles/{style}/{name}.json",
    "@acme-ui": "https://registry.acme.com/ui/{name}.json",
    "@acme-docs": "https://registry.acme.com/docs/{name}.json",
    "@private": {
      "url": "https://api.internal.com/registry/{name}.json",
      "headers": {
        "Authorization": "Bearer ${INTERNAL_TOKEN}"
      }
    }
  }
}

```

- **`@shadcn`**: The built-in registry populated automatically by the CLI constants.
- **`@acme-ui` and `@acme-docs`**: Public registries using simple string URLs where `{name}` is substituted with the component identifier.
- **`@private`**: An object-format registry supporting authentication headers. The `${INTERNAL_TOKEN}` syntax enables environment variable interpolation for secure credential management.

## Adding Components from Custom Sources

Once configured, installing components from any registry uses the standard CLI syntax. The namespace prefix directs the resolver to the appropriate registry URL template.

Execute the following to add a component from a custom registry:

```bash
npx shadcn@latest add @acme-ui/button

```

The CLI resolves `@acme-ui` against your [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json), substitutes `button` into the URL template `https://registry.acme.com/ui/{name}.json`, and downloads the component definition. It then writes the component files to your project according to the downloaded schema.

## Automatic Registry Discovery

The CLI includes automatic registry detection through the `ensureRegistriesInConfig` function in [`packages/shadcn/src/utils/registries.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/utils/registries.ts) (lines 24-31 and 66-79). When you attempt to add a component from an unconfigured namespace, this utility fetches the registry URL from the global index and updates your [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) automatically.

This TypeScript example demonstrates the programmatic API for registry discovery:

```typescript
import { ensureRegistriesInConfig } from "@/src/utils/registries";

await ensureRegistriesInConfig(
  ["@acme-ui/button", "@private/auth-utils"],
  config,
  { writeFile: true }
);

```

If `@private` was not previously listed in your configuration, the function resolves its URL from the global registry index and merges it into `config.registries` (see the merge logic at lines 66-79), then persists the changes to disk when `writeFile` is true.

## Summary

- **You configure multiple registries** by adding entries to the `registries` field in [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json), using either string URLs or object configurations with headers.
- **The `@shadcn` namespace is protected** and defined in [`packages/shadcn/src/registry/constants.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/registry/constants.ts), ensuring the official registry remains available.
- **Configuration merging** happens in [`packages/shadcn/src/utils/get-config.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/utils/get-config.ts), combining built-in and user-defined registries into a single lookup map.
- **Automatic discovery** via `ensureRegistriesInConfig` in [`packages/shadcn/src/utils/registries.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/utils/registries.ts) can populate missing namespaces by querying the global index.
- **Authentication is supported** through header objects in the registry configuration, with support for environment variable interpolation like `${INTERNAL_TOKEN}`.

## Frequently Asked Questions

### Can I override the official shadcn registry?

No, the official `@shadcn` registry is protected by the `BUILTIN_REGISTRIES` constant in [`packages/shadcn/src/registry/constants.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/registry/constants.ts). This design prevents accidental overrides and ensures that core components always resolve to the official source, even when you configure multiple registries in your project.

### How do I authenticate with private registries?

Use the object format in [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) to specify HTTP headers. You can include an `Authorization` header or other required credentials, and the CLI supports environment variable interpolation using the `${VAR_NAME}` syntax. This allows you to reference tokens like `${INTERNAL_TOKEN}` without committing secrets to version control.

### What URL patterns are supported for custom registries?

Registries must provide JSON endpoints that follow the pattern defined in your configuration, typically containing a `{name}` placeholder that the CLI substitutes with the component identifier. The URL can include any valid HTTP or HTTPS address, supporting query parameters, subdomains, and path variables as needed for your API structure.

### Does the CLI automatically detect new registry namespaces?

Yes, if you attempt to install a component from an unconfigured namespace, the CLI invokes `ensureRegistriesInConfig` from [`packages/shadcn/src/utils/registries.ts`](https://github.com/shadcn-ui/ui/blob/main/packages/shadcn/src/utils/registries.ts). This function checks the global registry index for the missing namespace, retrieves its URL configuration, and writes it back to your [`components.json`](https://github.com/shadcn-ui/ui/blob/main/components.json) file automatically, provided the registry is published to the index.