Relay - AI Chat UI Kit
Quick Start
Requirements: Node.js 18+ and npm. No environment variables, database, or API keys are needed to run - the homepage is the real ChatWindow component, streaming from seeded threads.
Download and unzip
Install dependencies
npm install
Start the dev server
npm run devOpen
http://localhost:3000 - that is the chat interface, no marketing site in front of it. Routes:/- the live ChatWindow; send a message or click a prompt card/login,/signup- mock auth, any email/password signs you in/app- the full threaded app once signed in: persistent sidebar, saved conversations,/app/chat/[threadId]for a specific thread/app/settings- Profile (usage stats), Appearance, API, Shortcuts
Cmd+K to jump to thread search, or ask about caching, model switching, or a pricing card to see the canvas/artifact system pop open.Build and lint
npm run build npm start # optional npx biome check . # lint
Folder Structure
Next.js App Router. Every screen reads from one typed data layer - the thread store persists to localStorage for the authenticated app, while the homepage runs an ephemeral copy of the same shape.
src/
├── app/
│ ├── page.tsx The homepage IS the ChatWindow, full viewport
│ ├── login/, signup/ Mock-auth pages (split-panel AuthLayout with a live preview)
│ └── app/
│ ├── layout.tsx Auth gate + ThreadStoreProvider + DashboardShell
│ ├── page.tsx Default chat screen (most recent thread)
│ ├── chat/[threadId]/ A specific saved thread
│ └── settings/ Profile + usage stats, appearance, API key, shortcuts
├── components/ ChatWindow, ChatMessageBubble, SourcesList, ArtifactPanel,
│ ChatComposer, CitationChip, ModelSelector, KeyCap, ...
└── lib/
├── types.ts ChatThread / ChatMessage / MessageSegment / ArtifactSegment / ...
├── mock-data.ts Seed threads, shortcuts
├── use-chat-stream.ts Token-by-token reveal hook (swap for a real stream)
├── thread-store.tsx Persisted (localStorage) thread store for /app
├── use-local-thread.ts Ephemeral thread state for the homepage demo
└── session.tsx Mock auth context (swap for Auth.js, Clerk, ...)Customization
Re-skin the whole kit
Every colour is a CSS custom property in src/app/globals.css - dark is the default theme (no class needed); :root.light supplies the light-mode override. Edit --theme-color-primary* to change the accent everywhere at once. Fonts: Big Shoulders (headings), Archivo (body), IBM Plex Mono (streamed tokens, citation stamps, code).
Make streaming real
useChatStream (src/lib/use-chat-stream.ts) reveals a message's text, code, and citation segments a few tokens at a time on a fixed interval. Replace the interval with a ReadableStream reader from your own streaming endpoint - every consumer only reads visibleSegments/isStreaming, so the swap stays local to that one file.
Artifacts and the canvas
A real model doesn't need to know about the canvas - fence code the normal way, and when you want it promoted to the canvas instead of rendered inline, wrap that segment as { type: "artifact", id, title, language, code } instead of { type: "code", ... }. ArtifactPanel handles the rest - auto-open, Copy, Download, and a sandboxed (allow-scripts, no allow-same-origin) live preview for HTML.
Persistence, models, and auth
Swap src/lib/thread-store.tsx's localStorage effects for calls to your own API/database - Sidebar, ChatWindow, and the chat pages only read/write through useThreadStore(). Route ModelSelector's selected id straight into your streaming call via the Vercel AI Gateway's "provider/model" string convention. Swap the three functions in src/lib/session.tsx (login/signup/logout) for your real auth provider - every consumer only calls useSession().
Deployment
The template runs fully seeded with none of .env.example's variables set - every one documents a real integration seam rather than something required to run the demo.
Deploy the demo
vercel.json sets the framework and build command. No database or API keys are required for the demo to work.Add keys only when you go live
.env.example to .env.local(or your host's dashboard) and set DATABASE_URL, AI_GATEWAY_API_KEY / DEFAULT_CHAT_MODEL, and AUTH_SECRET once you wire a real database, model, and auth provider.Build command: npm run build Start command: npm start Node version: 20+
Still stuck?
Email us at support@thekitbase.app with your order number and we'll help you get set up.