Easy Shadcn

Installation

Configure the @easy-shadcn registry and install components.

easy-shadcn components are distributed through the shadcn CLI. You can install them in two ways:

  • Recommended: Configure the @easy-shadcn namespace once, then install any component with a short command.
  • Quick try: Install directly via the full JSON URL — no configuration required.

Add a registries entry to your project's components.json:

components.json
{
  "registries": {
    "@easy-shadcn": "https://easy-shadcn.vercel.app/r/{name}.json"
  }
}

Then install any component using the namespace form:

pnpm dlx shadcn@latest add @easy-shadcn/card
pnpm dlx shadcn@latest add @easy-shadcn/modal

Cross-component dependencies (for example, modal depends on async-button) are resolved automatically through the same namespace — you don't need to install them by hand.

One-liner to patch components.json

If you'd rather not edit the file manually, run this command once at your project root:

node -e 'const f="components.json",fs=require("fs"),c=JSON.parse(fs.readFileSync(f,"utf8"));c.registries={...c.registries,"@easy-shadcn":"https://easy-shadcn.vercel.app/r/{name}.json"};fs.writeFileSync(f,JSON.stringify(c,null,2)+"\n")'

Alternative: Install via Full URL

You can skip the namespace config entirely and pass the JSON URL to the shadcn CLI:

pnpm dlx shadcn@latest add https://easy-shadcn.vercel.app/r/card.json
pnpm dlx shadcn@latest add https://easy-shadcn.vercel.app/r/modal.json

Zero configuration, but you'll need to type the full URL every time.

Why Namespaced?

  • Unambiguous: @easy-shadcn/card clearly comes from this registry and won't be confused with shadcn's built-in card.
  • Clean dependencies: Registry items can declare internal dependencies like @easy-shadcn/async-button, and the CLI resolves them through the namespace mapping.
  • Short commands: Once configured, the install experience matches the official shadcn flow.

@easy-shadcn is not a globally registered namespace — it's just a local alias in your components.json that points to this registry's URL template. You can rename the alias, but the registry's internal registryDependencies declare @easy-shadcn/..., so renaming it requires updating those references too. Keeping the default is recommended.

AI Agents / MCP

If you use an AI coding agent (Claude Code, Cursor, VS Code, Codex, opencode), the shadcn CLI ships an MCP server that lets the agent browse and install @easy-shadcn/* components on your behalf — no need to paste URLs or component names by hand.

First make sure the @easy-shadcn registry is configured in your components.json (see Recommended above). Then register the MCP server for your client:

pnpm dlx shadcn@latest mcp init --client claude
# other clients: --client cursor | vscode | codex | opencode

Once connected, ask the agent in natural language, for example:

"List the components available in the @easy-shadcn registry, then add the modal and card."

The agent reads your components.json, resolves the @easy-shadcn namespace, and runs the install for you — cross-component dependencies are resolved automatically.

For agents that consume plain text, this site also publishes the whole documentation set as LLM-friendly Markdown:

  • /llms.txt — an index of every page with a one-line description.
  • /llms-full.txt — the full docs concatenated as a single Markdown file.
  • Append .md to any docs URL for that page's raw Markdown, e.g. /docs/components/card.md.

Updating Components

easy-shadcn follows the shadcn copy-in model: add copies the component source into your project, so upgrading means re-running add with --overwrite:

pnpm dlx shadcn@latest add @easy-shadcn/card --overwrite

--overwrite replaces the local files, so any changes you made to the copied component will be lost. Commit or git diff first to review — if you've customized a component, reapply your edits after updating (or extend it from a wrapper in your own directory instead of editing the copy in place).

Localizing Built-in Text

Components ship with English defaults — "Loading…", "No data", "Pick an option", "OK" / "Cancel". There is deliberately no locale mechanism: the code is copied into your repo, so localization is a consumer-side concern. Three ways, from ad-hoc to app-wide:

  1. Pass props. Every built-in string has a prop: loadingMessage, emptyMessage, placeholder, confirmText / cancelText, and so on.
  2. Edit your copy. Change the default right in the file add dropped into your project. Note that upgrading with --overwrite resets it.
  3. Wrap and re-export (recommended for app-wide defaults). Bake your defaults into a wrapper you own — upgrades never touch it:
// components/app-table.tsx
import { Table, type TableProps } from "@/components/easy/table"

export function AppTable<T>(props: TableProps<T>) {
  return <Table emptyMessage="暂无数据" loadingMessage="加载中…" {...props} />
}

On this page