Architecture
The full path from your browser to the coding agent — WebSocket, the Node server, JSON-RPC over stdio to the provider CLI, and where your code actually goes.
Understanding the layers is the fastest way to debug T3 Code, because almost every failure belongs to exactly one of them — and the error message rarely says which.
The path#
┌─────────────────────────────────────────┐
│ Browser or Electron window │
│ React front end │
└───────────────┬─────────────────────────┘
│ WebSocket (ws://localhost:3773)
┌───────────────▼─────────────────────────┐
│ Node.js server on your machine │
│ sessions · threads · git · projects │
└───────────────┬─────────────────────────┘
│ JSON-RPC over stdio
┌───────────────▼─────────────────────────┐
│ Provider CLI subprocess │
│ e.g. codex app-server │
└───────────────┬─────────────────────────┘
│ HTTPS, your credentials
┌───────────────▼─────────────────────────┐
│ Model provider (OpenAI, Anthropic, …) │
└─────────────────────────────────────────┘Layer by layer#
1. The front end#
A React application, served either in your browser or inside an Electron window. Identical code in both cases — which is why a phone browser can connect to a desktop server and get the real interface.
It holds a persistent WebSocket to the server and renders structured events as they stream in. It has no direct filesystem or model access; everything goes through the socket.
2. The Node server#
The actual product. Runs on your machine on port 3773 and owns:
- Session and thread management, with persistent state across restarts
- Provider subprocesses — launching, monitoring, restarting them
- Git operations — worktrees, diffs, checkpoints, commits, pull requests
- Project registry — which repositories exist
- Pairing and auth for remote connections
- Serving the front end
3. The provider subprocess#
Per session, T3 Code launches your provider CLI in a server mode — for Codex, codex app-server — and speaks JSON-RPC over stdio to it. Structured events come back and are translated into WebSocket messages for the UI.
Two consequences worth internalising:
- T3 Code has no model access of its own. Authentication is entirely the CLI's. Your credentials live wherever the provider CLI keeps them.
- The protocol is a compatibility surface. If Codex changes its app-server protocol and T3 Code hasn't caught up — or your Codex is old and T3 Code is new — the handshake fails. That's the origin of the
Timed out waiting for initializeclass of bugs and of the request for explicit version compatibility checks.
4. The model provider#
The provider CLI talks to OpenAI, Anthropic or whoever, using your credentials. Nothing is proxied through a T3-operated server. Your code goes to your model provider, under your account, exactly as it would from the terminal.
That's the meaningful privacy claim: T3 Code changes the interface, not the trust boundary.
Debugging by layer#
The layer determines the fix. Match the symptom:
| Symptom | Layer | Where to look |
|---|---|---|
| UI loads, never connects | 1 → 2 | Browser console; is the server actually up? |
| Server won't start | 2 | Port conflict — 3773 in use |
| Server up, session won't start | 2 → 3 | Provider CLI version, PATH |
Timed out waiting for initialize | 3 | Old provider CLI |
'codex' not found | 2 → 3 | PATH inheritance |
| Session starts, then errors mid-run | 3 → 4 | Provider auth, rate limits, quota |
| Rate limits, billing errors | 4 | Your provider account, not T3 Code |
Why the design is right#
Wrapping CLIs instead of reimplementing agents has real consequences, and they're mostly good:
- New provider features arrive free. When Codex or Claude Code ships something, T3 Code inherits it without a release.
- Your existing auth and subscription carry over. No new billing relationship.
- Adding a provider means writing an adapter, not an agent — which is how it got to four providers quickly.
- You keep the escape hatch. Everything T3 Code does, you can do in a terminal. Nothing is locked in a proprietary format.
The cost is coupling: T3 Code is downstream of four CLIs it doesn't control, and their breaking changes are its breaking changes. Which is exactly why "update your provider CLI" is the first troubleshooting step for so many problems.
FAQ#
How does T3 Code work?#
Your browser holds a WebSocket to a Node server on your machine. That server launches your provider CLI as a subprocess and communicates with it over JSON-RPC on stdio, then streams structured events back to the UI.
Does T3 Code send my code to a server?#
Not to a T3-operated one. The server runs locally on your own machine, and your code goes only to your model provider through your provider CLI, using your credentials.
Does T3 Code need its own API key?#
No. It uses whatever your provider CLI is already authenticated with — your existing subscription or API key. T3 Code has no model access of its own.
Why does T3 Code break when my Codex CLI is outdated?#
T3 Code speaks JSON-RPC to codex app-server, and that protocol changes between Codex versions. Version skew breaks the handshake, typically surfacing as a session that hangs on startup.