N
Nyxis
getting started

Installation

Install Nyxis in any modern React project.

Nyxis ships through a shadcn-compatible registry. You install components and recipes with the standard shadcn CLI; they land as plain TypeScript files in your repo and are yours to edit.

Requirements

  • React 18 or 19
  • Tailwind CSS v4
  • shadcn CLI (already in the shadcn ecosystem — installed on demand via npx)

1. Bootstrap your project with shadcn

Start from any modern React-capable project. Then run shadcn’s initialiser — it writes components.json, lib/utils.ts, the design tokens, and the TypeScript path alias config Nyxis components rely on:

# Pick the framework starter you prefer:
npx create-next-app@latest      # Next.js (App Router)
npm create astro@latest         # Astro 5 + React + Tailwind
npx sv create                   # SvelteKit
npm create vite@latest          # Vite + React

# Then, inside the project:
npx shadcn@latest init

shadcn detects the framework automatically and writes the config in the right place. If detection fails (e.g. Astro without React enabled), shadcn prints what’s missing — usually a Tailwind config or the React integration.

Astro gotcha — path aliases. Astro’s default tsconfig.json doesn’t ship with compilerOptions.paths, so shadcn init fails with Could not find valid path aliases. Add this once and re-run:

{
  "extends": "astro/tsconfigs/strict",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

2. Install your first component

You don’t need to install anything else by hand. Pick a component and the shadcn CLI will install everything it needs — including @nyxis/core when applicable — in one go:

npx shadcn@latest add https://nyxisai.vercel.app/r/chat-thread.json

What this single command does, in order:

  1. Resolves the cascading registry dependencies (chat-thread pulls chat-message, which pulls utils).
  2. Installs every npm dependency declared by those items (@nyxis/core, lucide-react, etc.).
  3. Drops the source files into src/components/nyxis/<name>.tsx and src/lib/utils.ts.

Stateless components (e.g. chat-message) don’t need @nyxis/core and won’t pull it. Stateful ones (chat-thread, agent-roster) declare it in their manifest, so the CLI installs it for you. You never pnpm add @nyxis/core manually unless you want it without any component.

3. (Optional) Install the theme system

nyxis-ui is a separate, tiny npm package that ships:

  • The design tokens stylesheet (nyxis-ui/styles.css).
  • The five-mode theme runtime (light, dark, dim, high-contrast, system) and the FOUC-safe inline script.

Components render fine on shadcn’s default tokens, so nyxis-ui is optional. Install it when you want the Nyxis brand color, the dim and high-contrast themes, or the cross-tab theme switcher:

pnpm add nyxis-ui

In your global CSS:

@import 'tailwindcss';
@import 'nyxis-ui/styles.css';

The theme runtime needs a tiny inline script to run before any markup paints, otherwise users see a flash of the wrong theme. Pick the snippet for your framework:

Next.js (App Router)

import { getThemeScript } from 'nyxis-ui/theme';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <head>
        <script dangerouslySetInnerHTML={{ __html: getThemeScript() }} suppressHydrationWarning />
      </head>
      <body>{children}</body>
    </html>
  );
}

Astro

---
import { getThemeScript } from 'nyxis-ui/theme';
---

<!doctype html>
<html lang="en">
  <head>
    <script is:inline set:html={getThemeScript()} />
  </head>
  <body>
    <slot />
  </body>
</html>

is:inline is required so Astro doesn’t bundle the script — it has to run synchronously before the body paints.

SvelteKit

<!-- Replace %sveltekit.head% wrapper with: -->
<script>%nyxis.theme%</script>
%sveltekit.head%
import { getThemeScript } from 'nyxis-ui/theme';

export async function handle({ event, resolve }) {
  return resolve(event, {
    transformPageChunk: ({ html }) => html.replace('%nyxis.theme%', getThemeScript()),
  });
}

Vite (plain React)

import { getThemeScript } from 'nyxis-ui/theme';

const s = document.createElement('script');
s.textContent = getThemeScript();
document.head.prepend(s);

// then the usual createRoot(...).render(<App />)

The theme switcher itself is a registry item:

npx shadcn@latest add https://nyxisai.vercel.app/r/theme-toggle.json

4. Add more components

Pick anything else you need from the registry catalog:

npx shadcn@latest add https://nyxisai.vercel.app/r/agent-roster.json
npx shadcn@latest add https://nyxisai.vercel.app/r/rag-pipeline.json

Same flow as step 2 — the CLI:

  • Resolves cascading registry dependencies (e.g. agent-roster pulls agent-card, which pulls agent-status-badge, which pulls utils).
  • Installs npm dependencies declared by each item (@nyxis/core, lucide-react, framer-motion, etc.).
  • Drops source files into src/components/nyxis/<name>.tsx and src/lib/utils.ts.

Then import them as local modules. Next.js / SvelteKit / Vite treat them as ordinary client components:

'use client';

import { ChatMessage } from '@/components/nyxis/chat-message';
import { ChatThread } from '@/components/nyxis/chat-thread';
import { useChat } from '@nyxis/core';

export function Chat() {
  const { messages, append } = useChat({ api: '/api/chat' });
  return (
    <ChatThread messages={messages}>
      {messages.map((m) => (
        <ChatMessage key={m.id} role={m.role}>
          {m.content}
        </ChatMessage>
      ))}
    </ChatThread>
  );
}

Astro ships zero JS by default, so interactive Nyxis components must be hydrated as islands. Pick the directive that matches your need (client:load for above-the-fold, client:visible for below):

---
import { Chat } from '../components/Chat';
---

<Chat client:load />

This site itself is built on Astro and dogfoods every component it documents — see the live demos on the components pages.

Editing what you installed

Every file the CLI writes is plain TypeScript and plain Tailwind. There is no theming abstraction to fight. Change a class, drop a prop, swap a component — it is your file now.

Next steps

  • Read the Registry guide to learn how the catalog is organised and how to install many items at once.
  • Read the Theming guide for the five-mode token system.
  • Browse the catalog from the sidebar.