Skip to content

jakejarvis/_cn

Repository files navigation

_cn

underscorecn

An intentionally minimal TanStack Start + Vite+ starter template for publishing a shadcn-compatible registry without writing the documentation site and registry plumbing from scratch.

The scaffold contains a typed registry authoring layer, authored docs, live preview pages, syntax-highlighted source snippets, schema validation, package-manager install commands, and TanStack Start server routes. See a demo here.

Tip

_cn is pronounced "underscore-cn".

Quick Start

You can either create a new repository based on this template directly in your GitHub account/organization, or use a tool like degit to scaffold a fresh repo locally with the latest _cn code.

npx degit jakejarvis/_cn

# or use the "Use this template" button and then clone:
git clone https://github.com/your-username/my-cn.git

Once cloned, ensure you have Vite+ (vp) installed on your system; this will ensure all other requirements are taken care of for you.

# Install Vite+
curl -fsSL https://vite.plus | bash

# Setup and start local server
vp install
vp dev

Open the localhost URL from the Vite+ output and browse the starter docs, component, block, and utility pages. A good place to start customizing is the config.ts file.

Agent Skill

This repository includes an installable Agent Skill for authoring _cn registry items. Install it into your harness from the upstream template using the Skills CLI:

npx skills add jakejarvis/_cn --skill shadcn-registry

After installing the skill, ask your agent for registry authoring work directly:

  • "add a button component to the registry"
  • "adapt this modal from my app to make it reusable via this shadcn registry"
  • "add a reusable hook to the registry"
  • "turn this dashboard section into a registry block"

Deploy

Deploy with Vercel

Above is a one-click button to fork the template and deploy it to Vercel as a platform-agnostic Nitro server.

You can just as easily use any other platform (Cloudflare Workers, Netlify, etc.) by following the TanStack Start docs to make a few adjustments to your vite.config.ts file (agents are usually pretty good at this too).

Usage

Configuration

Edit registry/config.ts.

export const registryConfig = {
  name: "_cn",
  registryName: "_cn",
  namespace: "@_cn",
  description: "Installable components for your project.",
  homepage: "https://underscore-cn.vercel.app",
  repositoryUrl: "https://github.com/jakejarvis/_cn",
} as const;

Set homepage before deploying. Install commands and local registry dependency URLs are built from this value.

Author Docs

Create public documentation pages under registry/docs/.

registry/docs/
  index.mdx
  installation.mdx
  registry.mdx

Docs render under /docs: registry/docs/index.mdx becomes /docs, and registry/docs/installation.mdx becomes /docs/installation. Keep docs files directly under registry/docs for now; nested docs pages are not supported yet.

---
title: Installation
description: Install and run this registry.
order: 1
group: Getting Started
---

# Installation

Use Markdown or MDX with the built-in docs components.

Add A Registry Item

Automatic

Run bun --bun ./scripts/new.ts to interactively scaffold new registry items under registry/items/**.

It's always a good idea to also run bun --bun ./scripts/doctor.ts after making changes in the registry directory; this validates registry metadata and reports ignored or suspicious files within the directory.

Manual

Create a folder under registry/items/<section>/<item-name>/.

registry/items/components/example-card/
  _registry.mdx
  _preview.tsx
  example-card.tsx

Write metadata and usage docs in _registry.mdx.

---
name: example-card
type: registry:ui
title: Example Card
description: A compact card component.
registryDependencies:
  - card
localRegistryDependencies:
  - other-local-item
---

Use the component anywhere you need a compact content summary.

```tsx
import { ExampleCard } from "@/components/ui/example-card";

export function Example() {
  return <ExampleCard />;
}
```

Put the interactive preview in _preview.tsx.

"use client";

import { ExampleCard } from "./example-card";

export function Preview() {
  return <ExampleCard />;
}

For a one-file component, the catalog infers the source file from the item root and name, then emits a shadcn target placeholder such as @ui/example-card.tsx. List files explicitly in frontmatter for hooks, libs, blocks, pages, custom target paths, or any item with multiple published files; file paths are relative to the item _registry.mdx file. Metadata-only styles, themes, fonts, bases, and universal items can omit files. Do not publish _registry.mdx, _preview.tsx, or other authoring-only files.

The MDX body renders as the optional Usage section on the docs page. Fenced code blocks are syntax highlighted and keep the docs site's copy button. _preview.tsx is authoring-only and can use local state or events behind its "use client" boundary, but server-only logic should stay out of previews. Use localRegistryDependencies for dependencies on other local registry items; they are converted into canonical registry URLs in the public JSON.

Server

The public registry index is available at both the root and /r paths, while installable item JSON lives under /r:

  • /registry.json serves the registry index.
  • /r/registry.json serves the same registry index.
  • /r/<name>.json serves an item JSON file.
  • /llms.txt and /llms-full.txt are generated from the same Markdown docs and registry item pages used by the site.

Tip

_cn validates authored registry metadata against schemas directly from shadcn/schema to ensure compatibility.

Content Negotiation

Human-facing registry URLs support the shadcn CLI's request headers. CLI requests with Accept: application/vnd.shadcn.v1+json or User-Agent: shadcn receive the shadcn-compliant JSON from the same URL as the human-readable docs page:

  • /registry returns the registry index JSON.
  • /registry/<name> and section item pages like /components/<name> return item JSON.

All pages also support Markdown content negotiation (inspired by Fumadocs). AI clients that request text/markdown, text/x-markdown, or text/plain in the Accept header receive the Markdown version of the current page directly, while normal browser requests still receive HTML.

Checklist

  • Choose a registry name, namespace, domain, and repository URL in registry/config.ts.
  • Update or replace the starter docs under registry/docs.
  • Update or replace the starter registry items in registry/items; use bun --bun ./scripts/new.ts to generate new stubs.
  • Run bun --bun ./scripts/doctor.ts to verify changes.
  • Run vp check and vp build.
  • Deploy!
  • Test the install commands with npm, pnpm, yarn, bun, vite+, and deno.
  • Optionally submit your registry to shadcn's official directory.

Gotchas

Warning

The docs site uses the local shadcn UI configuration in components.json; that styling is for this app shell and does not affect the published registry items in any way.

License

MIT

About

πŸ‘¨β€πŸŽ¨ Plug-and-play shadcn/ui registry template, powered by TanStack Start

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors