Docs
deepmoon
Getting started
deepmoon is a shadcn/ui registry. There's no package to install. Every component ships as source into your own project via the shadcn CLI. Start with the theme, which sets up the color tokens, radius, type scale, and shadows every component reads from:
$ npx shadcn@latest add https://deepmoon.dev/r/deepmoon.jsonThen add components one at a time, as you need them:
$ npx shadcn@latest add https://deepmoon.dev/r/timeline.jsonEach install writes plain .tsx files into your components/directory, with no runtime dependency on deepmoon itself. Edit anything after it lands; there's nothing to eject.
Registry config
For repeat use, register deepmoon as a named registry in your project's components.json so you can reference components by name instead of full URLs:
{
"registries": {
"@deepmoon": {
"url": "https://deepmoon.dev/r/{name}.json"
}
}
}Then install with the namespace instead of a URL:
$ npx shadcn@latest add @deepmoon/timelineOr run npx shadcn@latest registry add @deepmoon=https://deepmoon.dev/r/{name}.json to have the CLI write that config for you.
Private registry
A handful of larger, composed blocks (dashboard sections pulled out of the paid dashboard templates — a kanban board, a Gantt chart, a schedule grid) are gated behind /r/private/* as part of the paid all-access tier. They require your license key as a bearer token and aren't reachable through the public registry index. The shadcn CLI's registriesconfig doesn't currently support custom auth headers, so the reliable path is a two-step: fetch the authenticated JSON yourself, then point the CLI at the local file.
curl -H "Authorization: Bearer $DEEPMOON_TOKEN" \
https://deepmoon.dev/r/private/your-component.json \
-o your-component.json
npx shadcn@latest add ./your-component.jsonThis works because shadcn addaccepts a local file path exactly like it accepts a URL: the file is a normal registry-item JSON payload once it's on disk. Set DEEPMOON_TOKEN to the license key from your purchase confirmation — anything that can hold a secret (CI, your shell profile, a password manager) works.
Theming
Every component reads color exclusively from CSS custom properties, never a hardcoded hex value. Structural tokens (radius, type scale, spacing, shadows) and neutrals (background, card, border, muted) are shared across all six variants; only the hue-bearing tokens change between them: --primary, --accent, --ring, and --chart-1 through --chart-5.
Deepmoon
deepmoon
Deepmoon Violet
deepmoon-violet
Deepmoon Emerald
deepmoon-emerald
Deepmoon Amber
deepmoon-amber
Deepmoon Rose
deepmoon-rose
Deepmoon Slate
deepmoon-slate
Switching variants at runtime
Each theme installs as a full set of CSS variables scoped under :root. To let users switch between variants without reinstalling, scope the non-default variants under a [data-theme="name"] attribute instead and toggle it on <html>, exactly how the switcher in this site's nav works. See registry/tokens/ in the source repo for how the six variants are composed from shared neutrals plus per-theme accent overrides.
Customizing tokens
Install a theme once, then edit the resulting CSS variables directly in your globals.css. There's no build step or config file mediating them. Changing --radius reshapes every component at once; changing --primary recolors every button, focus ring, and chart series that references it.
MCP setup
The shadcn CLI ships an MCP server that lets AI coding assistants search and install registry components directly, using whatever registries are configured in your project's components.json, including deepmoon once you've added it as shown above. Initialize it for your client:
$ npx shadcn@latest mcp init --client claudeSupported clients: claude, cursor, vscode, codex, opencode. This writes an MCP server entry (for Claude Code, a project-level .mcp.json) that runs npx shadcn@latest mcpon demand. Nothing stays running in the background. Once configured, you can ask your assistant to "search the deepmoon registry for a date picker" or "install the timeline component" and it will call the registry directly instead of guessing at an import.