• Goal: reach the same "scaffold UI" developer experience as shadcn/ui — copy-in component source, a CLI that stamps files + helpers + deps, a theming token model, and a registry — but Bun-native and SSR-first.
  • shadcn source: https://ui.shadcn.com/docs/cli, https://ui.shadcn.com/llms.txt
  • patties source of truth:
    • CLI impl: bun-patties-framework/packages/patties/src/cli/commands/add.ts (+ add/*)
    • Catalog package: bun-patties-framework/packages/patties-ui/ (src/registry.ts, src/types.ts, templates/)
    • Specs: agent_specs/ui/archive/** (catalog, all five phases archived) + draft specs under agent_specs/{cli,ui,framework}/draft/
  • Last reviewed: 2026-05-31
  • Last reclassified: 2026-05-31 (adopted the bun-coverage-matrix status taxonomy: shipped / specced / spec-later / divergent / deferred / out-of-scope, with a per-status relevant-gap headline)
  • 2026-05-31: rfc-patties-ui-theme-editor moved rfcs/deferred/ → new rfcs/out-of-scope/ (status: out-of-scope). Re-survey confirmed the visual editor is community/app-level (tweakcn etc.), not shadcn-core; theme distribution already covered by [[rfc-patties-ui-registries]]. deferred count 1 → 0; out-of-scope 3 → 4 (1 now carries an RFC file).
  • 2026-05-29: removed the three standalone rationale specs for divergent/out-of-scope rows (cli/16-search-list, cli/18-cli-non-goals, ui/61-config-model). Matching the bun matrix, those statuses carry no spec/RFC — the rationale lives inline in the § Divergent and § Out-of-scope tables. Only specced / spec-later / deferred rows have draft specs + RFCs.
  • 2026-05-29: promoted the registry-distribution cluster from spec-laterspecced (4 rows). [[rfc-patties-ui-registries]] moved rfcs/backlog/rfcs/accepted/ (status: encoded). specced is now 12, spec-later 0; accepted patties-ui RFCs now 8.
  • 2026-05-29: implemented the eight scaffold-ergonomics rows (ui config block, --path, ui init, view/--view, --diff/update, base-color presets, @theme inline wiring, migrate rtl/radix) — moved speccedshipped and archived specs cli/{11,12,13,14,17}, framework/25, ui/62 (draft/archive/, status: completed). shipped 12 → 20, specced 12 → 4 (registry distribution only). Catalog templates still use scattered @radix-ui/react-* imports (not yet the unified import) — tracked, see cli/17 implementation note.
  • 2026-05-30: implemented the registry-distribution cluster (4 rows: add <url>/add <local-path>, namespaced @ns/… registries, remote/URL registries, patties ui build) — moved speccedshipped and archived cli/15-registry-distribution (draft/archive/, status: completed). shipped 20 → 24, specced 4 → 0. The CLI classifies source kinds in add/source.ts (classifySource + temp-dir materialization so the existing stamp pipeline is reused unchanged) and fetches/validates via add/registry-fetch.ts (HTTPS-only unless --allow-insecure, payloads schema-checked against patties-ui/src/schema.ts); patties ui build emits a fetchable registry.json + per-component payloads with inlined source. Bun-native stance kept: fetched source is written verbatim, never executed, and no install is ever run. patties-ui is now publishable (zod dep + ./schema export); ComponentEntrySchema is the single source of truth (types.ts re-derives via z.infer).

This catalogue covers every shadcn CLI command, every add flag, the components.json config keys, the registry/distribution model, the theming surface, and the component catalog. Classification reflects whether patties ships the capability, has a draft spec for it, intentionally diverges, has parked it, or holds it out of scope.

Summary

StatusCountRFC file locationSpec
relevant-gap0— (would need a new RFC + draft spec)
shipped24— (no RFC — already in code)patties / patties-ui
specced0— (none currently)
spec-later (backlog)0— (none currently)
divergent9— (no RFC — design choice)rationale inline in § Divergent (dark mode also in ui/archive/62)
deferred0— (none currently)
out-of-scope43 no-RFC + 1 with an RFC (rfcs/out-of-scope/rfc-patties-ui-theme-editor, moved 2026-05-31)rationale inline in § Out-of-scope
Total catalogued37

The 8 accepted patties-ui RFCs (rfc-patties-ui-{update-diff, config-block, add-path, view, init, migrate, theming, registries}) have all now been implemented — one per shipped scaffold capability except theming (encodes both @theme inline wiring and base-color presets) and registries (encodes all four registry-distribution rows). No specced (accepted-but-unbuilt) rows remain.

Plus the 60-component catalog, all shipped (counted once as a shipped row above; the per-phase breakdown is in § Component catalog).

As of 2026-05-28 there are no relevant-gap rows. Every shadcn capability that applies to patties is either shipped, recorded as a deliberate divergence, deferred with a re-eval trigger, or out of scope. As of 2026-05-30 there are 0 specced rows: the eight scaffold-ergonomics rows shipped 2026-05-29 and the four registry-distribution rows shipped 2026-05-30. Every accepted parity RFC is now implemented — the remaining buckets are deliberate divergences, one deferral, and out-of-scope items, not pending work.

How to read the Status column

The taxonomy mirrors bun-coverage-matrix.md, including its RFC tree: patties-ui parity decisions are tracked as rfc-patties-ui-* RFCs under rfcs/{accepted,backlog,deferred}/, each encoding into a draft spec — exactly as the Bun-API RFCs (rfc-bun-*) do. (shadcn is the upstream reference, not the subject — hence rfc-patties-ui-*, never rfc-shadcn-*.)

  • shipped — implemented in patties today and exercised by code; no RFC needed. (bun-matrix analog: covered.)
  • specced — an accepted RFC (rfcs/accepted/rfc-patties-ui-*) that has landed in a draft spec, but no code yet. (analog: encoded.)
  • spec-later (backlog) — a backlog RFC (rfcs/backlog/): design on record, useful, not blocking, built on demand. (analog: rfc-later/backlog.)
  • divergent — patties intentionally does it differently; a deliberate design choice, not a missing feature. The capability exists in some form, retuned for the Bun-native / convention-over-config / SSR-first model.
  • deferred — a deferred RFC (rfcs/deferred/): considered and rejected for v1, with an explicit re-evaluation trigger. (analog: deferred.)
  • relevant-gap — shadcn has it, patties has neither code nor RFC/spec; would need a new RFC + draft spec. Currently 0.
  • out-of-scope — a shadcn capability that doesn't apply to the patties model at all; no RFC/spec warranted. (analog: out-of-scope.)

The framing this matrix codifies

patties-ui isn't "shadcn/ui, ported." It's "shadcn's scaffold experience, rebuilt knowing the constraints are Bun-native, copy-in, SSR-first, and convention-over-config." That reframing decides the buckets:

  • shadcn's components.json config axes (aliases, style, baseColor, rsc, tsx, cssVariables-on/off, iconLibrary) mostly become divergent/out-of-scope — patties replaces config with fixed conventions, exposing only the two paths that genuinely vary per project ([[framework/25-ui-config-block]]).
  • shadcn's eager npm install becomes a divergent by-design choice: patties edits package.json and never runs install (add.ts:73) — CI-safe, Bun-native.
  • shadcn's remote/npm registry model is now shipped (third-party / URL / namespaced registries + patties ui build, [[rfc-patties-ui-registries]] → cli/15); MCP/docs stays out-of-scope (patties' agent-manifest system is the analog surface).
  • The genuinely-missing scaffold ergonomics — init, --view, --diff/update, --path, presets, migrateshipped (2026-05-29), and remote/URL/namespaced installs + build shipped (2026-05-30); that was the real parity work.

Shipped (implemented today)

CapabilityCategoryshadcnpatties handling
add <component>CLI commandcopy source + depspatties add <component>, multi-name, fixed dest (add.ts:26)
add --allCLI command / flagstamp everythingfilters to status === "completed" (add.ts:55)
positional namesadd flagnames → installparseArgs collects non-flag args (add.ts:176)
--overwrite--forceadd flagoverwrite existingsame semantics, renamed; default never-overwrites (stamper skips existing)
--dry-runadd flagpreview planprints file plan + dep diff + token/helper plan (add.ts:107)
--cwd (global)add flagselect project rootglobal CLI flag applies
Component registry existsRegistryregistry.json (built)patties-ui/src/registry.ts (hand-maintained TS)
Typed registry entriesRegistryJSON schemaComponentEntry (types.ts): name, spec, phase, kind, island, status, files, peerDeps, helpers, tokens
Catalog populatedRegistry~60 components61 entries (hello fixture + 60 components), every entry status: "completed"
Resolved at command timeRegistryfrom registry URLBun.resolveSync("patties-ui/registry", cwd) (load-catalog.ts:20)
CSS-variable tokensTheming--background, --primarytemplates/tokens.css, merged idempotently (tokens.ts)
60-component catalogCatalog~60 live componentsall 60 stamped + registered completed (see § Component catalog)
add --diff / updateCLI command + flagdiff local vs upstreamshipped: line-level unified diff vs installed patties-ui; update re-stamps with force; --diff --check is a CI drift gate (cli/12)
--path <dir>add flagredirect destinationshipped: per-invocation destination; helpers follow, tokens don't; backed by config.ui.componentsDir (cli/14)
ui config blockConfig modelcomponents.json pathsshipped: optional componentsDir/internalDir/tokensFile, .strict(), project-root-escape guard (framework/25)
view / add --viewCLI command + flagpreview item before installshipped: metadata header + full template source; source to stdout (pipeable), header to stderr (cli/13)
ui initCLI commandbootstraps deps, CSS vars, aliasesshipped: merges tokens + cn helper + patches deps + prints @theme inline snippet (never edits app.css) (cli/11)
Tailwind v4 @theme inlineThemingyesshipped: wiring snippet printed by ui init; never auto-edits app.css (ui/62)
Base-color presetsThemingbaseColor, preset systemshipped: stamp-time `--theme neutral\slate\stone\zinc; idempotent token merge; no baseColor` key (ui/62)
migrate (rtl, radix)CLI commandcodemodsshipped: scanImports-detected scoped-regex rewrites, git-dirty guard, --dry-run; for user-authored code (cli/17)
add <url> / add <local-path>CLI commandinstall from URL/fileshipped: classifySource routes URL/local-path/namespaced/name; non-catalog sources materialized to a temp dir so the stamp pipeline is reused (cli/15)
Namespaced 3rd-party registries (@acme/…)Registryyesshipped: config.ui.registries maps @ns → https base or local path (cli/15)
Remote / URL registriesRegistryyesshipped: HTTPS-only (unless --allow-insecure), payloads schema-validated against patties-ui/schema, source previewed before stamp unless --yes, written verbatim, never executed (cli/15)
buildCLI command / Registrycompile registry.jsonshipped: patties ui build --out emits registry.json + per-component JSON with inlined source for 3rd-party authors; pure transform, no network/install (cli/15)

Specced (draft spec written, awaiting implementation)

None. All registry-distribution rows shipped 2026-05-30 (cli/15, [[rfc-patties-ui-registries]]); every accepted parity RFC is now implemented. The status remains in the taxonomy for future accepted-but-unbuilt work.

Spec-later (backlog — design on record, build on demand)

None. The registry-distribution cluster (remote/URL/namespaced installs + patties ui build) was promoted backlog → specced on 2026-05-29 and shipped on 2026-05-30 — its four rows now sit in the § Shipped table and cli/15 is archived. The status remains in the taxonomy for future parked work.

Divergent (intentional design difference)

CapabilityCategoryshadcnpatties divergenceRationale
eager npm installinstall behaviorinstalls depsedits package.json, prints bun install reminder, never installs (add.ts:73)Bun-native, CI-safe; refuses NODE_ENV=production (add.ts:34)
search / listCLI commandquery + --limit/--offset + namespaces--list prints the full local table (add.ts:139); optional name-filter + --jsonone local registry → pagination is pointless
--configadd flagpoint at a components.jsonno config file to point at; --cwd selects the projectnothing to point --config at
aliasesConfig modelimport-path rewritingderived from componentsDir, not a separate axisone path knob ([[rfc-patties-ui-config-block]]), not five
tailwind.css / cssVariablesConfig modelpath + vars on/offfixed tokensFile, CSS-vars always ona vars-off mode would fork every component
rsc / tsxConfig modelRSC + TS-flavor togglesalways SSR-island, always .tsx; no togglesisland model is the hydration boundary
style / baseColor (radix vs base)Config modelbase-library + base-color switchsingle style; base color is a token preset, not a library switchui/62-theming-presets covers the preset path
Distributed as a packageRegistrynpm registry / URLsstamped components are copy-in, never imported from a versioned package; patties-ui is publishable but only as the catalog the CLI reads, not a runtime depcopy-in model; remote/URL/namespaced distribution now shipped (cli/15) without making components a versioned import
Dark modeTheming.dark via next-themes.dark on <html>, zero JS theming dependencyno next-themes, no useTheme in stamped source. ui/62

Deferred (considered, rejected for v1, with re-eval trigger)

None currently. (The theme editor moved to out-of-scope on 2026-05-31 — see below.)

Out-of-scope (doesn't apply to the patties model)

Most out-of-scope rows carry no RFC (rationale inline). One exception: the theme editor was written up as a full RFC before being dismissed, so it retains a file in rfcs/out-of-scope/.

CapabilityCategoryshadcnReason
Theme editor / preset codes (preset decode/url/open)Theminglive editor + shareable preset URLs[[rfc-patties-ui-theme-editor]] (out-of-scope 2026-05-31) — the visual editor is community/app-level (tweakcn, themecn, shadcn/studio), not part of shadcn-core or its CLI. shadcn-core ships only base-color presets + @theme inline, already encoded in ui/62. Theme distribution is already covered by [[rfc-patties-ui-registries]]. If shareable preset codes ever get real demand, that is a fresh registry-adjacent RFC, not a revival of this one.
infoCLI commandprint resolved components.json + envno components.json to report; config-loading diagnostics + --list --json cover the rest
mcp / docsCLI commandserve registry over MCP / fetch docspatties' agent-manifest system (CLAUDE.md/AGENTS.md) is the analog surface
iconLibraryConfig modelconfigurable default icon setfixed lucide-react; copy-in means the user owns and edits the import — a config key would imply indirection that doesn't exist

Component catalog

The 60-component catalog is fully specced and fully implemented — all shipped. The spec index lives in agent_specs/ui/archive/00-overview.md (phases 0–4, all archived).

PhaseThemeComponentsIn registry.tsTemplate file exists
1Zero-JS primitives181818
2Form primitives + Button121212
3Radix-backed islands212121
4Recipes & heavy islands999
Phase-0 fixture1 (hello)11

Every component is registered with status: "completed" and has a stamped template; patties add <name> stamps source + _internal/ helpers + tokens.css + peer deps, idempotent on re-run. shadcn parity on the catalog is "full" per spec intent (every component full except Form/Toast, kept as compat).

Implementation order

Items 1–7 shipped on 2026-05-29/30 (all specs archived):

  1. ~~add --diff / update~~ — shipped (cli/12). The copy-in model's biggest weakness was upstream drift.
  2. ~~--path + ui config block~~ — shipped (cli/14, framework/25).
  3. ~~view / source preview~~ — shipped (cli/13).
  4. ~~ui init~~ — shipped (cli/11).
  5. ~~Theme presets / base color~~ — shipped (ui/62). Stamp-time --theme <name>.
  6. ~~migrate (rtl, radix)~~ — shipped (cli/17). For user-authored/imported code.
  7. ~~Remote / namespaced registries + build~~ — shipped 2026-05-30 (cli/15, [[rfc-patties-ui-registries]]). Source-kind classification + temp-dir materialization, HTTPS-only schema-validated fetch, and patties ui build for 3rd-party authors.

Re-running this audit

# 1. Refresh shadcn surface
#    CLI:  https://ui.shadcn.com/docs/cli
#    Index: https://ui.shadcn.com/llms.txt   (component list + count)

# 2. Cross-reference against patties code
cd bun-patties-framework
#    CLI surface:
grep -nE '"--[a-z-]+"|runAdd|parseArgs|printList' packages/patties/src/cli/commands/add.ts
#    Registry shape + catalog count:
grep -c 'name:' packages/patties-ui/src/registry.ts
ls packages/patties-ui/templates/*.tsx | wc -l

# 3. Cross-reference against draft specs
cd ../bun-patties-docs
ls agent_specs/cli/draft/ agent_specs/ui/draft/ agent_specs/framework/draft/

# 4. Diff against the RFC tree (mirrors bun-coverage-matrix):
ls agent_specs/rfcs/accepted/rfc-patties-ui-* \
   agent_specs/rfcs/backlog/rfc-patties-ui-* \
   agent_specs/rfcs/deferred/rfc-patties-ui-*

# 5. Re-classify each shadcn capability into:
#    shipped | specced | spec-later | divergent | deferred | relevant-gap | out-of-scope
# 6. A `relevant-gap` row means a missing RFC — open rfcs/draft/rfc-patties-ui-<slug>,
#    accept it (→ rfcs/accepted/), encode into a draft spec under
#    agent_specs/{cli,ui,framework}/draft/, then flip the row to `specced`.
#    Promote backlog → accepted when a trigger fires.
# 7. Keep the summary counts in lockstep with the section tables AND the RFC tree.

Reviewer note: the rfcs/ tree holds two RFC families — rfc-bun-* (Bun-API coverage, tracked by bun-coverage-matrix.md) and rfc-patties-ui-* (shadcn-parity, tracked here). shadcn is the upstream reference, so the RFCs are named for the patties-ui subject, never rfc-shadcn-*. Each specced/spec-later/deferred row above has a matching RFC carrying its verdict + upstream_shadcn / comparable_elsewhere / trigger metadata in frontmatter, exactly as the Bun RFCs do — so promotions edit one place (the RFC) and update the matrix from it.