Getting started
Installation
With the shadcn CLI#
This is the quickest route. Each component is published as a shadcn registry item, so the CLI writes the file, installs its npm dependencies and adds lib/neon.ts for you.
Set up shadcn (skip if you already use it)
This creates
components.jsonandlib/utils.ts.npx shadcn@latest initAdd a component
npx shadcn@latest add https://get-neonkit.vercel.app/r/switch.jsonPass several URLs to add them in one go.
npx shadcn@latest add https://get-neonkit.vercel.app/r/tabs.json https://get-neonkit.vercel.app/r/toast.json https://get-neonkit.vercel.app/r/slider.jsonUse it
import { Switch } from "@/components/ui/switch" export default function Page() { return <Switch color="lime" label="Neon on" defaultChecked /> }
NeonKit writes to the same components/ui folder as shadcn/ui. If a file with the same name exists (a fresh shadcn init ships a button), the CLI asks first. Add --overwrite to replace it without asking.
Short names#
Register the @neonkit namespace in components.json and drop the URLs. This also makes NeonKit visible to the shadcn MCP server.
{
"registries": {
"@neonkit": "https://get-neonkit.vercel.app/r/{name}.json"
}
}npx shadcn@latest add @neonkit/button @neonkit/selectManual#
Prefer to see every line? It takes about a minute.
Install the two class helpers
npm install clsx tailwind-mergeSome components also use
motion,lucide-reactor@radix-ui/react-slot. Each component page lists what it needs.Add
lib/utils.tslib/utils.tsimport { type ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); }Add
lib/neon.tsThe palette and the one helper that turns a color into the CSS variable.
lib/neon.tsimport type * as React from "react"; /** * The NeonKit palette, stored as space-separated RGB channels so components * can apply any alpha with `rgb(var(--neon) / 0.4)`. */ export const neonColors = { cyan: "34 211 238", blue: "79 139 255", violet: "168 85 247", magenta: "240 70 235", pink: "255 95 162", red: "255 77 94", orange: "255 138 61", amber: "251 191 36", lime: "163 230 53", green: "52 211 153", white: "230 237 247", } as const; export type NeonColorName = keyof typeof neonColors; /** A palette name or any hex color (`#0ff`, `#ff00aa`). */ export type NeonColor = NeonColorName | (string & {}); export const neonColorNames = Object.keys(neonColors) as NeonColorName[]; /** Resolves a palette name or hex string to `"r g b"` channels. */ export function toNeonRgb(color: NeonColor): string { if (color in neonColors) return neonColors[color as NeonColorName]; let hex = color.trim().replace(/^#/, ""); if (hex.length === 3) hex = hex.replace(/./g, (c) => c + c); if (!/^[0-9a-f]{6}$/i.test(hex)) return neonColors.cyan; const value = parseInt(hex, 16); return `${(value >> 16) & 255} ${(value >> 8) & 255} ${value & 255}`; } /** * Inline style that sets a component's neon color. * * Components read `--neon`. Leave `color` undefined and they inherit * `--neon-accent` from any ancestor, falling back to cyan. */ export function neonVars( color?: NeonColor, style?: React.CSSProperties, ): React.CSSProperties | undefined { if (!color) return style; const rgb = toNeonRgb(color); return { "--neon": rgb, "--neon-accent": rgb, ...style } as React.CSSProperties; }Check the path alias
Components import from
@/lib/…. Most templates set this up already.tsconfig.json{ "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["./*"] } } }Copy a component
Open any component, choose Manual and paste the source into
components/ui.
Tailwind 3#
The components avoid utilities that were renamed in v4 and style everything through arbitrary values, so they compile the same on 3.4. Make sure your content globs include the folder you paste them into.
module.exports = {
content: ["./app/**/*.{ts,tsx}", "./components/**/*.{ts,tsx}"],
}Background#
NeonKit is dark only. The glows are tuned against #05060a, and anything close to black works.
<body className="bg-[#05060a] text-white antialiased">