docs/solutions/developer-experience/2026-05-24-plate-init-routes-should-return-shadcn-registry-base-items.md
Upstream shadcn's /init route is part of the CLI bootstrap contract. It returns a registry:base item whose config is merged into components.json; it is not a generic components.json download endpoint.
Plate needed an init surface for the shadcn-base restart, but copying upstream v0/create behavior would bring in the wrong product flow.
apps/www had /view/[name] parity but no /init or /init.md route.@plate, while content/docs/installation/mcp*.mdx still documented @platejs.components.json from /init. The shadcn CLI expects a registry item there; a config-only endpoint would look useful in a browser and still be the wrong installer API./init/v0. Plate does not own the v0 generation flow, and keeping v0 routes is fork residue.@platejs sends users and agents toward a registry that templates do not configure.Add a shared Plate registry config and expose it through a shadcn registry:base item:
export const plateComponentsJsonConfig = {
$schema: 'https://ui.shadcn.com/schema.json',
style: 'new-york',
rsc: true,
tsx: true,
tailwind: {
config: '',
css: 'src/app/globals.css',
baseColor: 'neutral',
cssVariables: true,
prefix: '',
},
aliases: {
components: '@/components',
utils: '@/lib/utils',
ui: '@/components/ui',
lib: '@/lib',
hooks: '@/hooks',
},
iconLibrary: 'lucide',
registries: {
'@plate': 'https://platejs.org/r/{name}.json',
},
} as const;
Then validate the init payload with the upstream shadcn schema:
export const plateInitRegistryItem = registryItemSchema.parse({
$schema: 'https://ui.shadcn.com/schema/registry-item.json',
name: 'plate',
title: 'Plate',
description: 'Initialize a shadcn project with the Plate registry.',
type: 'registry:base',
extends: 'none',
config: plateComponentsJsonConfig,
registryDependencies: ['@plate/editor-basic'],
});
Expose:
/init -> JSON registry:base/init/md -> markdown instructions/init.md -> rewrite to /init/mdKeep /init/v0 absent, and fix MCP docs snippets to use @plate.
shadcn init --preset https://platejs.org/init resolves the first component as a registry item. When that item is registry:base, the CLI extracts its config, merges it into components.json, filters built-in registries, and then installs the item dependencies.
That gives Plate the one bootstrap it actually needs: configure the @plate namespace and install @plate/editor-basic, while leaving upstream create/v0 product features out of the Plate docs app.
packages/shadcn/src/commands/init.ts and packages/shadcn/src/preset/presets.ts.registryItemSchema from shadcn/schema.type: "registry:base", extends: "none", config.registries["@plate"], and the @plate/editor-basic dependency./init, /init.md, and /init/v0 together. The last one should stay 404 unless Plate intentionally adopts a real v0 flow.rg -n '"@platejs"|@platejs": "https://platejs.org/r' content/docs apps/www/src