# Shadcn Parity

> Clone shadcn implementation patterns with source-by-source parity. Use when the user says "shadcn parity", asks to mirror shadcn, copy shadcn UX/architecture/tests, or wants more than inspiration.

- Skill: `udecode/shadcn-parity` (Agent Skill)
- Install (CLI): `npx skillmds add udecode/shadcn-parity`
- Raw SKILL.md: https://api.skillmd.com/api/skills/udecode/shadcn-parity/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: udecode (https://skillmd.com/u/udecode)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/udecode/shadcn-parity

---


# Shadcn Parity

## Core Contract

When the user asks for shadcn parity, treat `../shadcn` as the source of
truth for registry behavior and patterns.

Do not give them "inspired by shadcn". Do not invent a Plate-specific model
when upstream shadcn already has one.

The rule is simple:

- upstream schema first
- upstream resolver behavior first
- upstream file/layout patterns first
- upstream namespace semantics first
- Plate divergence only when the repo has a real constraint

Plate does **not** fork shadcn CLI. Do not talk about Plate as if it owns a
custom installer. Plate owns a registry and template sync layer around the
upstream shadcn contract.

If you diverge, say exactly why.

## Ownership

Shadcn owns the contract:

- registry item schema
- namespace semantics like `@shadcn/button` and other registry prefixes
- resolver behavior for plain items, namespaced items, URLs, and local files
- local-file add behavior
- `components.json` registry semantics

Plate owns the content and delivery:

- registry source files under `apps/www/src/registry/*`
- registry build logic in `apps/www/scripts/build-registry.mts`
- generated registry output under `apps/www/public/r` and `apps/www/public/rd`
- the `@plate` namespace configured in template `components.json`
- template sync tooling in:
  - `tooling/scripts/update-template.sh`
  - `tooling/scripts/prepare-local-template-registry.mjs`

Important boundary:

- shadcn owns how registry items are resolved and installed
- Plate owns what the registry contains and how local template sync feeds it

Plate's registry build is custom. The goal is still upstream parity at the
item and resolver boundary.

## Registry Rules

Registry items should stay as close as possible to upstream `RegistryItem`
shape.

When building or changing Plate registry items:

- check `../shadcn` first
- copy upstream file/layout/helper patterns when they fit
- prefer upstream naming and dependency structure over Plate-specific novelty
- keep dynamic Plate-specific behavior in build or sync tooling, not in a fake
  registry data model

Registry dependency rules:

- prefer `@shadcn/*` when an upstream shadcn item exists
- prefer upstream namespace syntax over raw URLs when the namespace already
  covers the case
- if upstream does not expose a small standalone item, use a small Plate
  registry item instead of dragging in a huge upstream dependency just to steal
  one internal file
- do not expand compatibility hacks into new conventions

Do not fork shadcn CLI to compensate for Plate registry problems. Fix the
registry data or the Plate sync tooling instead.

## Template Rules

For template installs, shadcn CLI is still the installer. Plate supplies the
registry.

Template rules:

- keep `templates/*/components.json` aligned with shadcn registry semantics
- treat `@plate` in `components.json` as the install entrypoint for Plate
  items
- prefer registry fixes over template-only patches when generated output is
  wrong
- compare Plate output against `../shadcn` before inventing a custom rule

For local template sync:

- `--local` uses local-file mode, not localhost
- local sync works by preparing a JSON mirror from `apps/www/public/rd`
- local sync exists to feed upstream shadcn local-file install flow, not to
  replace it

If a change would make public installs cleaner but would break local-file sync,
call that out and fix both sides together.

## Current Divergences

These are real Plate divergences today. Treat them as constraints, not as a
pattern to spread.

- Plate publishes a registry from `apps/www`, not from upstream shadcn
  infrastructure
- local template sync uses prepared JSON mirrors and local-file mode
- template install entrypoints use the `@plate` registry in `components.json`
- some built registry output may still emit absolute Plate self-URLs for
  compatibility; treat that as behavior to minimize, not a new model to copy

## Red Flags

Stop and reassess if you are about to do any of this:

- describe Plate as a fork of shadcn CLI
- invent a new Plate-only registry schema
- replace upstream namespace behavior with raw URL sprawl
- solve a registry issue by adding more installer logic when the data is wrong
- patch templates by hand without checking whether the registry source is the
  real problem

