How to Use the shadcn Search Command to Find Components in the Registry

The shadcn search command (aliased as list) queries any Shadcn registry—built-in or custom—using fuzzy matching against component names and descriptions, returning paginated JSON results via the CLI or programmatic API.

The shadcn search command is a core feature of the shadcn-ui/ui CLI that enables developers to discover installable UI components without browsing documentation. Whether you are targeting the official @shadcn registry or a privately hosted custom registry, the command handles configuration loading, registry validation, and fuzzy search execution through a pipeline defined in the source code.

Understanding the shadcn Search Command Architecture

CLI Registration and Entry Point

The search command is registered in the global CLI entry point at packages/shadcn/src/index.ts (lines 32-39). It is added alongside other commands like init, add, and diff:

program
  .addCommand(init)
  .addCommand(create)
  .addCommand(add)
  .addCommand(diff)
  .addCommand(view)
  .addCommand(search)   // Registers 'search' and 'list' aliases
  .addCommand(migrate)

Command Parsing and Configuration

The command implementation resides in packages/shadcn/src/commands/search.ts (starting at line 25). It accepts several options:

  • --cwd <path>: Working directory (defaults to process.cwd())
  • --query <text>: Fuzzy search string for filtering components
  • --limit <number>: Maximum results to return (default 100)
  • --offset <number>: Number of results to skip for pagination

The command first loads the local components.json configuration. If the file is missing or incomplete, it constructs a shadow config using defaults (style: "new-york") to ensure the search pipeline always has valid configuration (lines 66-75).

Registry Resolution and Validation

Before executing the search, the command normalizes registry identifiers through ensureRegistriesInConfig (lines 88-99). This helper:

  1. Converts namespace-style registries (e.g., @shadcn) to their full registry paths (@shadcn/registry)
  2. Validates that custom URLs are properly formatted
  3. Merges new registries into the configuration without writing to disk (writeFile: false)

The command then validates all registries using validateRegistryConfigForItems (line 101) to ensure they can serve component metadata.

Search Execution and Fuzzy Matching

The core search logic lives in packages/shadcn/src/registry/search.ts (lines 8-61). The searchRegistries function performs the following steps:

  1. Fetch registry data: For each registry, it calls getRegistry (from registry/api.ts), which downloads and validates the registry's components.json against registrySchema.
  2. Flatten items: Maps each registry's items to a uniform structure including name, type, description, registry, and addCommandArgument.
  3. Fuzzy filtering: If a query is provided, the internal searchItems helper (lines 76-104) uses fuzzysort to match against both name and description fields.
  4. Pagination: Applies offset and limit to the results, returning a pagination object with total, offset, limit, and hasMore flags.

The final output is validated against searchResultsSchema and returned as JSON.

Using the shadcn Search Command: Practical Examples

Basic CLI Usage

To search the official registry for button components:

npx shadcn search @shadcn -q button

This returns a JSON array of components matching "button" in their name or description.

Advanced Filtering and Pagination

For large registries, use pagination to browse results incrementally:


# Get 5 results, skipping the first 10

npx shadcn search @shadcn -q modal -l 5 -o 10

The output includes a pagination object indicating if more results are available via hasMore: true.

Searching Multiple Registries

You can query multiple registries simultaneously by providing additional arguments:

npx shadcn search @shadcn https://example.com/my-registry -q card

The command normalizes both namespace-style (@shadcn) and full URL registries before executing the search.

Programmatic Usage in Node.js

You can import the search functionality directly in scripts for custom tooling:

import { searchRegistries } from "@shadcn/ui/registry/search"
import { getConfig } from "@shadcn/ui/utils/get-config"

async function findComponents() {
  const config = await getConfig(process.cwd())
  
  const result = await searchRegistries(
    ["@shadcn"],                    // Registry identifiers
    { 
      query: "button", 
      limit: 10,
      offset: 0,
      config 
    }
  )
  
  console.log(result.items)           // Array of matching components
  console.log(result.pagination)    // { total, offset, limit, hasMore }
}

findComponents()

This approach leverages the same fuzzy search and validation logic used by the CLI.

Key Source Files and Implementation Details

File Purpose Location
packages/shadcn/src/index.ts CLI entry point that registers the search command View Source
packages/shadcn/src/commands/search.ts Command definition, argument parsing, config loading, and registry validation View Source
packages/shadcn/src/registry/search.ts Core search algorithm including fuzzy matching and pagination View Source
packages/shadcn/src/registry/api.ts Registry fetching and validation via getRegistry and fetchRegistry View Source
packages/shadcn/src/schema.ts Zod schemas for registry items and search results validation View Source

Summary

  • The shadcn search command (aliased as list) queries component registries using fuzzy matching against names and descriptions.
  • It supports both built-in namespaces (@shadcn) and custom registry URLs, normalizing them through ensureRegistriesInConfig.
  • The command implements shadow configuration to work with partial or missing components.json files.
  • Fuzzy search is powered by fuzzysort in packages/shadcn/src/registry/search.ts, with pagination controlled via --limit and --offset flags.
  • Output is structured JSON suitable for piping to other tools or programmatic consumption via the searchRegistries API.

Frequently Asked Questions

What is the difference between shadcn search and shadcn list?

There is no functional difference—list is simply an alias for search registered in the CLI at packages/shadcn/src/index.ts. Both commands invoke the same underlying logic in packages/shadcn/src/commands/search.ts and accept identical options for querying, limiting, and offsetting results.

How does the shadcn search command handle fuzzy matching?

The command uses the fuzzysort library to perform fuzzy string matching against both the name and description fields of registry items. This logic resides in the searchItems helper within packages/shadcn/src/registry/search.ts (lines 76-104). The matching is case-insensitive and tolerates typos, returning results ranked by relevance score.

Can I search custom registries with the shadcn search command?

Yes. The command accepts any number of registry arguments, which can be either namespace-style identifiers like @shadcn or full URLs such as https://example.com/my-registry. The ensureRegistriesInConfig function in packages/shadcn/src/commands/search.ts normalizes these inputs and validates them before executing the search across all specified sources.

Pagination is controlled via the --limit (-l) and --offset (-o) flags. For example, npx shadcn search @shadcn -l 10 -o 20 returns 10 results starting from the 21st item. The JSON output includes a pagination object with total, offset, limit, and hasMore properties, allowing you to determine if additional pages exist.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →