Nodea is a branching AI chat canvas. Every reply becomes a node you can fork from — your conversation grows as a tree of branches, not one long thread that you keep scrolling. Built on Anthropic Claude. Free during beta.
Live product: https://nodea.ai — open a canvas, no credit card, no waitlist.
Nodea is a non-linear interface for chatting with Anthropic's Claude models. Instead of one linear thread per conversation, every message you and the AI exchange is stored as a node in a tree. From any node, you can branch — ask the same question a different way, explore an alternative plan, compare two phrasings — without overwriting or losing the original path.
The product is for people who think by exploring alternatives: writers, researchers, founders, engineers, anyone who notices that "regenerate" and "start new chat" both destroy useful context.
| Linear chat (ChatGPT, Claude.ai) | Nodea | |
|---|---|---|
| Conversation shape | A list | A tree |
| Try a different answer | Edit message (destroys history) or new chat (loses context) | Branch from any node, original stays put |
| See all explored paths | No | Yes — visible on the canvas |
| Compare two answers | Two tabs, manually | Side-by-side, same canvas |
| Search across branches | One thread at a time | Across every path |
Long-form explainer with architecture and design notes: nodea.ai/what-is-nodea.
This repo is the source for the hosted Nodea product at nodea.ai. It contains:
- The marketing site (
/,/what-is-nodea,/blog,/compare/*,/upgrade) - The chat app itself (
/app— three-panel canvas with sidebar, chat, and tree) - The admin dashboard (
/admin— usage analytics, traffic, model routing) - The Stripe billing integration, Supabase auth, and Claude streaming endpoints
It's MIT-licensed — fork it, self-host it, or read it to understand the architecture.
- Branching from any reply — the data model is a tree of nodes; the UI is a view onto that tree
- Tree canvas — XYFlow surface with free pan/zoom over the whole conversation graph
- Model routing — auto-selects Claude Haiku 4.5, Sonnet 4.6, or Opus 4.7 by prompt complexity and plan tier
- Streaming responses — token-by-token via the Vercel AI SDK
- Search — live keyword search plus semantic ("concept") search via Claude
- Anonymous mode — start a canvas without signing up; claim it later by linking an email
- Color-coded nodes — tag the keepers, skim a project at a glance
- Stripe billing — $0 free (25k daily / 450k monthly tokens), $8/mo Pro for Claude Opus + 50k daily / 1M monthly tokens
| Layer | Technology |
|---|---|
| Framework | Next.js 16.2 (App Router), React 19 |
| Language | TypeScript 5 |
| Styling | Tailwind CSS v4 + CSS variable theming |
| Database + auth | Supabase (Postgres with RLS, Supabase Auth) |
| AI streaming | Vercel AI SDK v6 (ai + @ai-sdk/anthropic) |
| Models | Anthropic Claude — Haiku 4.5, Sonnet 4.6, Opus 4.7 |
| Canvas | XYFlow (React Flow) |
| Billing | Stripe Checkout + Customer Portal |
| Deployment | Vercel |
- Node.js v18 or later
- A Supabase project
- An Anthropic API key
- A Stripe account (only required for Pro plan billing)
git clone https://github.com/Elliott-Crosby/Nodea.git
cd Nodea
npm installCreate a .env.local file in the project root. Never commit this file.
# Supabase — Project Settings > API
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
# Anthropic — console.anthropic.com > API Keys
ANTHROPIC_API_KEY=
# Stripe — Dashboard > Developers > API Keys
STRIPE_SECRET_KEY=
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=npm run devOpen http://localhost:3000.
nodea/
├── public/ # Static assets
├── src/
│ └── app/ # Next.js App Router — pages, layouts, API routes
│ ├── _components/ # Shared UI (landing sections, page tracker)
│ ├── admin/ # Admin dashboard — analytics, traffic, usage
│ ├── api/
│ │ ├── admin/ # Analytics + traffic endpoints
│ │ ├── autotitle/ # AI-powered conversation title generation
│ │ ├── chat/ # Main Claude streaming endpoint
│ │ ├── projects/ # Project (conversation) CRUD
│ │ ├── search/ # Keyword + concept search
│ │ ├── stripe/ # Checkout, portal, webhook
│ │ └── track*/ # Page-view + event tracking
│ ├── app/ # Main canvas — chat + tree + sidebar
│ ├── blog/ # /blog index + posts
│ ├── compare/ # /compare/* head-to-head pages
│ ├── login/ # Login + password reset
│ ├── upgrade/ # Pricing page
│ └── what-is-nodea/ # Long-form explainer
├── supabase/migrations/ # Database schema migrations
├── AGENTS.md # AI agent instructions
├── CLAUDE.md # Claude Code project config
└── package.json
Two tables — that's the whole branching engine.
projects (id, user_id, name, created_at)
nodes (id, project_id, parent_id, role, content,
position_x, position_y, created_at)
A conversation is a project. Every message is a node with a single parent_id. Branching is just inserting a new node whose parent_id points to some existing node. The chat panel for a selected node is the chain you get by walking parent_id back to null. Row-level security (auth.uid() = user_id) isolates users.
npm run dev # Start development server
npm run build # Production build
npm start # Run production build
npm run lint # Run ESLintDeploy to Vercel — connect this repository, add the environment variables above in the Vercel project settings, and deploy. The production deploy serves nodea.ai.
- 🌐 Product: nodea.ai
- 📖 What is Nodea?: nodea.ai/what-is-nodea
- 📝 Blog: nodea.ai/blog
- 💬 Discussions: github.com/Elliott-Crosby/Nodea/discussions
- 🏢 Source: github.com/Elliott-Crosby/Nodea
- Fork this repository
- Create a branch:
git checkout -b feature/your-feature - Commit:
git commit -m 'Add your feature' - Push:
git push origin feature/your-feature - Open a Pull Request