Install Guide
Add thegridcn components, themes, and tokens to any shadcn/ui project with a single CLI call.
Install guide · shadcn CLI
The GridCN ships a shadcn/ui-compatible registry. Every component is a single npx shadcn add away, either by namespace (@thegridcn/button) or by full URL.
Prerequisites
A project that shadcn/ui can write into:
- Next.js 14+, Vite, Remix, or any React project supported by shadcn.
- Tailwind CSS 3.4+ (Tailwind 4 is recommended — that's what The GridCN uses).
- A
components.jsonat the project root. If you don't have one yet:
npx shadcn@latest initAnswer the prompts for style, base color (pick neutral), and CSS variables (say yes).
Register the namespace (recommended)
Add @thegridcn once to your components.json and skip typing URLs:
{
"registries": {
"@thegridcn": "https://thegridcn.com/r/{name}.json"
}
}From then on, every item is a short name away:
# base shadcn component (our version, re-exported)
npx shadcn@latest add @thegridcn/button
# tron-flavored component
npx shadcn@latest add @thegridcn/data-card
npx shadcn@latest add @thegridcn/radar
npx shadcn@latest add @thegridcn/hud
# install several at once
npx shadcn@latest add @thegridcn/button @thegridcn/data-card @thegridcn/hud
# 3D component (pulls in three + @react-three/fiber)
npx shadcn@latest add @thegridcn/gridYou can also search and list the registry:
npx shadcn@latest search @thegridcn
npx shadcn@latest search @thegridcn --query "hud"
npx shadcn@latest list @thegridcnInstall by full URL (no setup)
If you'd rather not edit components.json, pass the full URL:
npx shadcn@latest add https://thegridcn.com/r/button.json
npx shadcn@latest add https://thegridcn.com/r/data-card.jsonThe CLI will:
- Fetch the JSON manifest.
- Resolve
registryDependencies(sibling registry entries). - Resolve
dependencies(npm packages) and install them with your package manager. - Write the TSX to
src/components/ui/(base) orsrc/components/thegridcn/(Tron), honoring yourcomponents.jsonaliases.
Install a theme
Themes ship as registry:style items that write a single CSS file with the oklch() variables baked in:
npx shadcn@latest add @thegridcn/theme-ares
npx shadcn@latest add @thegridcn/theme-tron
npx shadcn@latest add @thegridcn/theme-clu
npx shadcn@latest add @thegridcn/theme-athena
npx shadcn@latest add @thegridcn/theme-aphrodite
npx shadcn@latest add @thegridcn/theme-poseidonEach writes to src/styles/thegridcn-theme.css. Import it from your global CSS:
/* src/app/globals.css */
@import "tailwindcss";
@import "../styles/thegridcn-theme.css";If you want multiple themes side-by-side with data-theme switching, use the raw token files instead (see Tokens export below).
Listing available components
Every registry entry is mirrored under public/r/ and served at /r/<name>.json. The canonical list lives in registry.json at the project root. To enumerate names locally:
# from a clone of thegridcn-ui
jq -r '.items[].name' registry.json | sort -uTo enumerate names from the live site:
curl -s https://thegridcn.com/registry.json | jq -r '.items[].name' | sort -uComplete example
Install a button, a Tron data card, the Ares theme, then render it.
# 1. init shadcn if you haven't
npx shadcn@latest init
# 2. register the namespace in components.json
# "registries": { "@thegridcn": "https://thegridcn.com/r/{name}.json" }
# 3. install everything in one shot
npx shadcn@latest add @thegridcn/theme-ares @thegridcn/button @thegridcn/data-card// app/page.tsx
import { Button } from "@/components/ui/button";
import { DataCard } from "@/components/thegridcn/data-card";
export default function Page() {
return (
<div className="min-h-screen bg-background p-8">
<DataCard
subtitle="PROGRAM"
title="FLYNN"
status="active"
fields={[
{ label: "STATUS", value: "ACTIVE" },
{ label: "TYPE", value: "USER" },
]}
/>
<Button className="mt-6">Enter the Grid</Button>
</div>
);
}Tokens export
If you'd rather not install a full theme style file, grab just the CSS variables:
- CSS:
https://thegridcn.com/tokens/<theme>.css - JSON:
https://thegridcn.com/tokens/<theme>.json - Manifest:
https://thegridcn.com/tokens/index.json
Available theme names: tron, ares, clu, athena, aphrodite, poseidon.
/* drop into your app's globals.css */
@import "https://thegridcn.com/tokens/ares.css";Or regenerate locally:
pnpm tokens:buildTroubleshooting
Component "foo" not found
Check the exact name in registry.json — some Tron variants are prefixed (thegridcn-badge, thegridcn-timeline, etc.) to disambiguate from the base shadcn component.
Cannot find module '@/components/ui/...'
Your components.json aliases don't match The GridCN's defaults. Either align your aliases (components: "@/components", ui: "@/components/ui") or update the imports after install.
Tailwind classes not applying
The GridCN is built on Tailwind 4. On Tailwind 3 most utilities work, but you'll need to port @theme inline blocks from src/app/globals.css to your tailwind.config.*. The tokens/<theme>.json file is the easiest bridge.
3D components fail to render
The Three.js components (grid, tunnel, grid-floor) must be dynamically imported with ssr: false in Next.js:
import dynamic from "next/dynamic";
const Grid3D = dynamic(() => import("@/components/thegridcn/grid").then(m => m.Grid), {
ssr: false,
});Multiple themes on one page
Wrap the section in <div data-theme="tron">…</div> after importing each theme CSS or the raw tokens. The data-theme attribute cascades CSS variables locally.
Registry compatibility status
The registry is generated by shadcn build (see pnpm registry:build) and follows the registry-item.json schema. It is consumed out-of-the-box by npx shadcn@latest add <url>.
Verified working:
- Single-file
registry:componentitems (base + tron). - Items with
dependencies(npm) andregistryDependencies(sibling items). registry:styletheme items.
Known limitations:
- The
components.jsonin this repo includes a large inlinedregistriesfield used internally for the showcase's live source preview. Consumers of the registry don't need it — they only need their owncomponents.jsonscaffolded byshadcn init. - The 3D components don't declare
ssr: falsein their registry entries. Consumers must wrap them withdynamic(..., { ssr: false })themselves (see Troubleshooting).
If you hit anything else, open an issue at the repo.