shadcn/ui

Use shadcn/ui components in your NukeJS project. Because NukeJS doesn't use RSC, setup takes a few manual steps — but the CLI handles everything after that.

shadcn/ui is a collection of accessible, composable components you copy directly into your project. Since NukeJS doesn't use React Server Components in the RSC sense, follow the manual installation path rather than a framework-specific preset.

1. Install Tailwind CSS

shadcn/ui is styled with Tailwind CSS. If you haven't set it up yet, follow the Tailwind CSS guide first, then come back here.

2. Install dependencies

terminalbash
npm install shadcn class-variance-authority clsx tailwind-merge lucide-react tw-animate-css

3. Configure path aliases

shadcn/ui uses @/ path aliases. Add them to your tsconfig.json:

tsconfig.jsonjson
{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@/*": ["./*"]
        }
    }
}

4. Configure styles

Add the shadcn CSS variables to your global stylesheet. In NukeJS, that lives at app/public/main.css:

app/public/main.csstypescript
@import "tailwindcss";
@import "tw-animate-css";
@import "shadcn/tailwind.css";

@custom-variant dark (&:is(.dark *));

@theme inline {
    --color-background: var(--background);
    --color-foreground: var(--foreground);
    --color-card: var(--card);
    --color-card-foreground: var(--card-foreground);
    --color-popover: var(--popover);
    --color-popover-foreground: var(--popover-foreground);
    --color-primary: var(--primary);
    --color-primary-foreground: var(--primary-foreground);
    --color-secondary: var(--secondary);
    --color-secondary-foreground: var(--secondary-foreground);
    --color-muted: var(--muted);
    --color-muted-foreground: var(--muted-foreground);
    --color-accent: var(--accent);
    --color-accent-foreground: var(--accent-foreground);
    --color-destructive: var(--destructive);
    --color-border: var(--border);
    --color-input: var(--input);
    --color-ring: var(--ring);
    --radius-sm: calc(var(--radius) * 0.6);
    --radius-md: calc(var(--radius) * 0.8);
    --radius-lg: var(--radius);
    --radius-xl: calc(var(--radius) * 1.4);
}

:root {
    --radius: 0.625rem;
    --background: oklch(1 0 0);
    --foreground: oklch(0.145 0 0);
    --card: oklch(1 0 0);
    --card-foreground: oklch(0.145 0 0);
    --popover: oklch(1 0 0);
    --popover-foreground: oklch(0.145 0 0);
    --primary: oklch(0.205 0 0);
    --primary-foreground: oklch(0.985 0 0);
    --secondary: oklch(0.97 0 0);
    --secondary-foreground: oklch(0.205 0 0);
    --muted: oklch(0.97 0 0);
    --muted-foreground: oklch(0.556 0 0);
    --accent: oklch(0.97 0 0);
    --accent-foreground: oklch(0.205 0 0);
    --destructive: oklch(0.577 0.245 27.325);
    --border: oklch(0.922 0 0);
    --input: oklch(0.922 0 0);
    --ring: oklch(0.708 0 0);
}

.dark {
    --background: oklch(0.145 0 0);
    --foreground: oklch(0.985 0 0);
    --card: oklch(0.205 0 0);
    --card-foreground: oklch(0.985 0 0);
    --primary: oklch(0.922 0 0);
    --primary-foreground: oklch(0.205 0 0);
    --secondary: oklch(0.269 0 0);
    --secondary-foreground: oklch(0.985 0 0);
    --muted: oklch(0.269 0 0);
    --muted-foreground: oklch(0.708 0 0);
    --accent: oklch(0.269 0 0);
    --accent-foreground: oklch(0.985 0 0);
    --destructive: oklch(0.704 0.191 22.216);
    --border: oklch(1 0 0 / 10%);
    --input: oklch(1 0 0 / 15%);
    --ring: oklch(0.556 0 0);
}

@layer base {
    * { @apply border-border outline-ring/50; }
    body { @apply bg-background text-foreground; }
}

5. Add the cn helper

app/lib/utils.tstypescript
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"

export function cn(...inputs: ClassValue[]) {
    return twMerge(clsx(inputs))
}

6. Create components.json

Create a components.json at the project root. The aliases below match the NukeJS project structure:

components.jsonjson
{
    "$schema": "https://ui.shadcn.com/schema.json",
    "style": "radix-nova",
    "rsc": false,
    "tsx": true,
    "tailwind": {
        "config": "",
        "css": "app/public/main.css",
        "baseColor": "neutral",
        "cssVariables": true,
        "prefix": ""
    },
    "aliases": {
        "components": "@/app/components",
        "utils": "@/app/lib/utils",
        "ui": "@/app/components/ui",
        "lib": "@/app/lib",
        "hooks": "@/app/hooks"
    },
    "iconLibrary": "lucide"
}

Note "rsc": false — NukeJS doesn't use React Server Components in the RSC sense, so this tells the CLI not to add "use client" directives automatically (you'll add them yourself where needed).

7. Add components with the CLI

With components.json in place, the shadcn CLI can install components directly into your project:

terminalbash
npx shadcn@latest add input
npx shadcn@latest add button
npx shadcn@latest add dialog

Components are copied into app/components/ui/ — they're plain TypeScript files you own and can edit freely.

8. Use in a client component

shadcn components use React hooks internally, so any component that imports them must be a "use client" component in NukeJS:

app/components/ContactForm.tsxtypescript
"use client"
import { useState } from "react"
import { Button } from "@/app/components/ui/button"
import { Input } from "@/app/components/ui/input"

export default function ContactForm() {
    const [email, setEmail] = useState("")

    return (
        <form className="flex gap-2">
            <Input
                type="email"
                placeholder="your@email.com"
                value={email}
                onChange={e => setEmail(e.target.value)}
            />
            <Button type="submit">Subscribe</Button>
        </form>
    )
}

Then drop it into any server page — NukeJS will SSR the HTML and hydrate only this component:

app/pages/index.tsxtypescript
import ContactForm from "../components/ContactForm"

export default function Home() {
    return (
        <main>
            <h1>Stay in the loop</h1>
            <ContactForm />
        </main>
    )
}

Available components

The full component catalogue — Button, Dialog, Select, Table, and 50+ more — is at ui.shadcn.com/docs/components. Each page includes copy-pasteable code and live previews.