Marginalia - Chat With Your Documents
Quick Start
Requirements: Node.js 18+. The app runs in demo mode out of the box - no database, API keys, or environment variables are required to see the full product.
Download and unzip
Install dependencies
npm install
Start the dev server
npm run devOpen
http://localhost:3000. Key routes:/- marketing landing that demos the citation-linked chat/pricing,/login,/signup,/onboarding- plans and a 3-step setup wizard/app- workspace overview;/app/documents- library with live ingestion and the source viewer/app/chat/conv-1- the citation-linked chat (the signature surface);/app/settings,/app/billing
Build and test
npm run build npm start
Folder Structure
Next.js App Router. Every screen in demo mode reads from one typed data layer - src/lib/mock-data.ts - so going live means swapping its helpers for real queries behind the same function signatures, not rewriting the UI.
src/
├── app/
│ ├── layout.tsx # Fonts (Fraunces + Geist), flash-free theme, providers
│ ├── globals.css # "Reading Room" design tokens (@theme) - porcelain + sienna accent
│ ├── page.tsx # Marketing landing (hero demos the citation chat)
│ ├── pricing/page.tsx # Plans + comparison + FAQ
│ ├── login | signup/page.tsx # Auth (mock-auth-first)
│ ├── onboarding/page.tsx # 3-step setup wizard
│ └── app/
│ ├── page.tsx # Workspace overview
│ ├── documents/ # Library + ingestion state machine, source viewer
│ ├── chat/[conversationId]/ # Citation-linked RAG chat
│ ├── settings/ # Profile / workspace / members
│ └── billing/ # Plans, usage, invoices (Dodo seam)
├── components/ # AppShell, ChatSurface, DocumentsView, SourceViewer, ...
└── lib/
├── types.ts # Domain types - mirror your live backend's shapes here
├── mock-data.ts # Demo corpus + retrieve() / answerFor() - the live-mode seam
└── icons.tsx # Inline icon setCustomization
Reskin - "Reading Room"
Warm porcelain neutrals with a sienna citation accent, defined once in src/app/globals.css: --accent-cite, --accent-cite-hover, and --accent-cite-light (the citation highlight), plus --accent-brass* for rules and eyebrows. Typography pairs Fraunces (display/serif) with Geist (UI) and Geist Mono (citations and document references) in src/app/layout.tsx.
Going live: swap the retrieval seam
Demo mode answers from a seeded corpus via retrieve() and answerFor() in src/lib/mock-data.ts. To go live: provision Neon and enable pgvector, store uploads in R2, embed chunks through the Vercel AI Gateway (EMBEDDING_MODEL), replace retrieve() with an embedding query plus a pgvector similarity search scoped by workspace, and stream generation with CHAT_MODEL via the AI SDK - keep the same return shapes and the chat, source viewer, and citation UI need no changes.
Auth and billing seams
Auth is mock-first - replace the session logic with your provider (e.g. NextAuth). Billing UI is driven by BillingView.tsx; wire startCheckout() there to Dodo Payments using your per-plan product IDs.
Deployment
The app builds and runs in demo mode with zero configuration, so preview deploys work immediately.
Deploy the demo
Add keys only when you go live
.env.example to .env.local(or your host's dashboard) and set DATABASE_URL (Neon + pgvector), AI_GATEWAY_API_KEY, CHAT_MODEL, EMBEDDING_MODEL, R2_*, DODO_*, and RESEND_API_KEY / EMAIL_FROM once you wire the live pipeline.Still stuck?
Email us at support@thekitbase.app with your order number and we'll help you get set up.