How to Set Up t3code Locally: A Complete Development Guide
To set up t3code locally, clone the pingdotgg/t3code repository, install dependencies with Bun using bun install, and run bun run dev to start the development server on ports 5173 (web UI) and 3773 (WebSocket server).
t3code is a minimal web GUI that wraps the Codex and Claude coding agents, built as a Node.js WebSocket server with a React frontend. Whether you want to contribute to the open-source project or run your own instance, this guide covers everything you need to set up t3code locally from the pingdotgg/t3code repository.
Prerequisites
Before you set up t3code locally, ensure you have the following installed:
- Node.js ≥ 20 – The runtime requirement for the server.
- Bun – The package manager used throughout the monorepo. Install it from https://bun.sh.
- Optional: Mise – For managing dev tool versions (the repo includes a
.mise.toml). - Codex or Claude providers – Must be installed and authenticated separately (see the repository README Installation section).
Step-by-Step Local Setup
Clone the Repository
Start by cloning the t3code repository and entering the directory:
git clone https://github.com/pingdotgg/t3code.git
cd t3code
Install Dev Tools (Optional)
If you use Mise for version management, install the pinned tool versions:
mise install
Install Dependencies
Use Bun to install all packages across the monorepo:
bun install .
This respects the lockfile and installs dependencies for the web app, server, and shared packages.
Start the Development Server
Run the development server with hot reload:
bun run dev
This command starts two services:
- The React/Vite web UI on
http://localhost:5173 - The Node.js WebSocket server on port
3773, establishing the bridge between the browser and the coding agents
Desktop Development (Electron)
For the Electron-based desktop application, use:
bun run dev:desktop
To run an isolated instance for feature-branch testing:
T3CODE_DEV_INSTANCE=feature-xyz bun run dev:desktop
Build for Production
Compile the web UI and start the production server:
bun run build
bun run start
Create macOS Distribution
Build a shareable .dmg file (default targets arm64):
bun run dist:desktop:dmg
Run Without Local Installation
Launch the latest released binary from any directory using npx:
npx t3
Architecture Overview
Understanding the architecture helps when you set up t3code locally for development or debugging.
Browser Layer
The frontend is a React application that communicates through a typed WebSocket transport. Key files include:
apps/web/src/wsTransport.ts– Handles message encoding/decodingapps/web/src/wsNativeApi.ts– Native API bindings
Server Layer
The Node.js process hosts the web UI, manages provider sessions, and pushes ordered events to clients:
apps/server/src/wsServer.ts– WebSocket entry point handling connections and readiness gatingapps/server/src/provider/Layers/ProviderService.ts– Session management and provider orchestration
Provider Runtime
The external codex app-server executes code-agent actions via JSON-RPC over stdio:
apps/server/src/codexAppServerManager.ts– Spawns and manages the Codex process
Core Implementation Details
Starting a Codex Session
When the UI initiates a session, the server routes the request through ProviderService to codexAppServerManager:
// apps/server/src/provider/Layers/ProviderService.ts
await providerService.startSession({
provider: "codex",
binaryPath: "/usr/local/bin/codex",
runtimeMode: RuntimeMode.Interactive,
});
Background Worker Processing
The server uses DrainableWorker (located in packages/shared/src/DrainableWorker.ts) to process async work like checkpointing:
// apps/server/src/orchestration/Layers/CheckpointReactor.ts
await this.worker.enqueue(async () => {
// compute diff, persist checkpoint, emit receipt
});
This guarantees deterministic ordering for tests and UI updates.
Runtime Event Handling
The server listens for turn completion via RuntimeReceiptBus:
// apps/server/src/orchestration/Layers/RuntimeReceiptBus.ts
runtimeReceiptBus.on("turnQuiescent", (turnId) => {
console.log(`Turn ${turnId} is fully quiescent`);
});
Events push to the browser via ServerPushBus, enabling real-time UI updates without polling.
Key Files to Explore
| Path | Purpose |
|---|---|
apps/server/src/codexAppServerManager.ts |
Manages Codex app-server spawning and JSON-RPC communication |
apps/server/src/wsServer.ts |
WebSocket server entry point and client connection handling |
apps/web/src/wsTransport.ts |
Browser-side WebSocket transport layer |
packages/contracts/src/ws.ts |
Shared TypeScript contracts for WebSocket messages |
packages/shared/src/DrainableWorker.ts |
Deterministic async worker implementation |
.docs/architecture.md |
Visual system overview and event lifecycle diagrams |
.docs/quick-start.md |
Command reference for development workflows |
Summary
- t3code is a Node.js WebSocket server wrapping Codex/Claude agents, served by a React/Vite frontend.
- To set up t3code locally, you need Node ≥ 20, Bun, and optionally Mise for version management.
- Run
bun installfollowed bybun run devto start the development environment on ports 5173 (web) and 3773 (server). - Use
bun run dev:desktopfor Electron development andbun run dist:desktop:dmgto build macOS installers. - The architecture separates concerns into Browser (
wsTransport.ts), Server (wsServer.ts,ProviderService.ts), and Provider Runtime (codexAppServerManager.ts).
Frequently Asked Questions
What are the exact Node.js and Bun versions required to set up t3code locally?
You need Node.js version 20 or higher and the latest Bun package manager. The repository includes a .mise.toml file if you use Mise to manage these tool versions automatically.
Can I run t3code without installing it locally?
Yes. You can run the latest released binary without cloning the repository by executing npx t3 from any directory. This is useful for one-off usage without the local development setup.
How do I run a separate desktop instance for testing feature branches?
Set the T3CODE_DEV_INSTANCE environment variable to a unique identifier before running the desktop dev command:
T3CODE_DEV_INSTANCE=feature-xyz bun run dev:desktop
This creates an isolated Electron instance useful for testing changes without affecting your main development environment.
What is the difference between bun run dev and bun run start?
bun run dev starts the development environment with hot reloading, concurrently running the Vite dev server (port 5173) and the Node.js WebSocket server (port 3773). bun run start runs the compiled production server after you have built the assets with bun run build.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →