Architecture
The three computers, what runs on each, and what happens between a sentence being typed and an answer arriving.
This page is the map. Nothing here is needed to run the installation, and everything here is needed to reason about it: when something is slow, when a feature says it is not configured, or when you are deciding whether a change belongs in the panel or in the code.
The three computers
The browser, which is the product
React 19 behind the App Router. The editor is Monaco, the preview of a project is a sandboxed frame, and the bundler that makes that preview possible is esbuild compiled to WebAssembly, running in a worker on the reader's own machine. Nothing about a project is built on your server until it is deployed.
The app, which is one Node process
The routes in app/: the marketing site, the product, the panel, the
documentation, the API the browser calls, and the public share pages. It
holds the vault key, the connect credentials and the API keys, because the
code that uses them runs here. It has no database of its own and keeps
nothing on disk.
The deployment, which is Convex
The schema, the queries and mutations, the actions, the accounts and
sessions, the scheduled jobs, the uploaded files. This is the only place
data lives. It is deployed on its own, with npx convex deploy, and it has
its own environment.
Everybody else, which is configuration
The model gateway, the mail provider, the payment gateways, the Git providers, the deployment targets, the databases a project can be given. None of them are required, and each one that is missing switches off its own feature with a reason rather than breaking a page.
The layers, and what belongs in each
| Layer | Folder | The rule for what goes here |
|---|---|---|
| Routes | app/ | Anything with a URL: a page, a route handler, an image, a redirect |
| Interface | components/ | Everything drawn, grouped by where it is used |
| Rules | lib/ | Pure functions with tests beside them: plans, credits, limits, flags, entitlements |
| Backend | convex/ | Anything that touches data, sessions, schedules, or somebody else's API with a secret |
| Content | content/docs/ | This manual, which is MDX rather than code |
The boundary that matters most is between app/ and convex/. A query reads data. A mutation writes it. An
action calls the outside world. A route handler in app/ is what the browser talks to, and it is where a
request is checked before anything else happens. If a change needs a secret that the browser must never see,
it belongs on the deployment. If it needs a key that the deployment does not hold, it belongs in a route.
One turn, from a sentence to an answer
The sentence is sent to a route
The browser posts to /api/chat. The route is a streaming response, so the
answer arrives as it is written rather than all at once. This is the request
a reverse proxy must not buffer.
The installation is read
One read of the settings decides most of what happens next: which models are live, what the agent has been told, which tools the plan allows, where the spend ceiling is. The panel writes these, so a change in the panel changes the next turn.
The plan is checked before the work is done
Rate limits and entitlements come first, then credits: a running turn reserves credits against itself rather than spending them at the end. A refusal at this point costs nothing and says which window was hit.
The model is called through the gateway
One key reaches every vendor. The model is chosen by capability and tier rather than by name, which is why swapping the model behind a feature is a setting rather than a change of code.
Tools run on the deployment
Reading a project's files, searching the web, generating a picture, remembering something: each is a call back into the deployment, and each is written down as it happens so the conversation can be replayed.
The turn is settled and remembered
Credits are settled against what was actually used, the message is stored, and the conversation's history moves on. A turn that fails gives its reservation back, which is why a failed turn costs nothing.
Why the reservation exists
Credits are reserved when a turn starts and settled when it finishes. That is what makes "in flight" a different number from "spent" on the dashboard, and it is also what stops two turns arriving at once from both spending the last of an allowance.
What runs without anybody asking
The scheduled work lives on the deployment, so there is no worker to keep alive, no queue to drain and no cron
of yours to configure. The jobs are described in lib/jobs.ts, run through one function, and the panel's
Platform → Jobs & queue shows when each last ran and whether it failed.
| Kind of job | Examples |
|---|---|
| Deadlines made out loud | A thing in the bin is recoverable for a window, and then it is not |
| The week | Credit windows resetting, allowances being granted for the new window |
| Housekeeping | Retention sweeps, rate counters, the audit trail's own sweep |
| Reaching out | Reminders, and the messages a plan change is worth telling somebody about |
Where data actually is
| Kind of thing | Where it lives | Backed up by |
|---|---|---|
| Accounts, projects, conversations | The deployment's tables | The provider's backup, and System → Backups |
| Uploaded files and generated images | The deployment's file storage | The provider, plus whatever you copy out |
| Sealed tokens and provider keys | The deployment, encrypted with SETTINGS_SECRET | A snapshot, readable only with that same secret |
| An installation's settings | The deployment's tables, one document per section | A snapshot |
| The code | This folder | Wherever you keep it |
Nothing is stored in the app's process, which is what makes the app disposable: the folder can be replaced, moved or rebuilt from nothing, and the installation is still there.
Why it is shaped this way
The stack, with versions
| Piece | What it is |
|---|---|
| Next.js 16, React 19 | App Router, server components, streaming, Turbopack |
| Tailwind CSS v4 | The whole design system, in app/globals.css |
| Convex | Database, functions, scheduler, file storage, HTTP routes |
| Better Auth | Accounts, sessions, the OAuth flows, running on the deployment |
| Vercel AI SDK | Model calls, streaming, tools |
| Motion, shadcn/ui, Animate UI | The interface and its movement |
| Monaco, esbuild-wasm | The editor and the in-browser bundler |
| Streamdown, KaTeX, Mermaid | Answers with tables, equations and diagrams |
| Vitest | The tests, beside the files they test |

