# How to Set Up t3code Locally: A Complete Development Guide

> Easily set up t3code locally by cloning the repository, installing dependencies with Bun, and running `bun run dev`. Start your T3 stack development today!

- Repository: [Ping.gg/t3code](https://github.com/pingdotgg/t3code)
- Tags: getting-started
- Published: 2026-04-18

---

**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`](https://github.com/pingdotgg/t3code/blob/main/.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:

```bash
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:

```bash
mise install

```

### Install Dependencies

Use Bun to install all packages across the monorepo:

```bash
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:

```bash
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:

```bash
bun run dev:desktop

```

To run an isolated instance for feature-branch testing:

```bash
T3CODE_DEV_INSTANCE=feature-xyz bun run dev:desktop

```

### Build for Production

Compile the web UI and start the production server:

```bash
bun run build
bun run start

```

### Create macOS Distribution

Build a shareable `.dmg` file (default targets `arm64`):

```bash
bun run dist:desktop:dmg

```

### Run Without Local Installation

Launch the latest released binary from any directory using npx:

```bash
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`](https://github.com/pingdotgg/t3code/blob/main/apps/web/src/wsTransport.ts) – Handles message encoding/decoding
- [`apps/web/src/wsNativeApi.ts`](https://github.com/pingdotgg/t3code/blob/main/apps/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`](https://github.com/pingdotgg/t3code/blob/main/apps/server/src/wsServer.ts) – WebSocket entry point handling connections and readiness gating
- [`apps/server/src/provider/Layers/ProviderService.ts`](https://github.com/pingdotgg/t3code/blob/main/apps/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`](https://github.com/pingdotgg/t3code/blob/main/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`:

```typescript
// 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`](https://github.com/pingdotgg/t3code/blob/main/packages/shared/src/DrainableWorker.ts)) to process async work like checkpointing:

```typescript
// 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`:

```typescript
// 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`](https://github.com/pingdotgg/t3code/blob/main/apps/server/src/codexAppServerManager.ts) | Manages Codex app-server spawning and JSON-RPC communication |
| [`apps/server/src/wsServer.ts`](https://github.com/pingdotgg/t3code/blob/main/apps/server/src/wsServer.ts) | WebSocket server entry point and client connection handling |
| [`apps/web/src/wsTransport.ts`](https://github.com/pingdotgg/t3code/blob/main/apps/web/src/wsTransport.ts) | Browser-side WebSocket transport layer |
| [`packages/contracts/src/ws.ts`](https://github.com/pingdotgg/t3code/blob/main/packages/contracts/src/ws.ts) | Shared TypeScript contracts for WebSocket messages |
| [`packages/shared/src/DrainableWorker.ts`](https://github.com/pingdotgg/t3code/blob/main/packages/shared/src/DrainableWorker.ts) | Deterministic async worker implementation |
| [`.docs/architecture.md`](https://github.com/pingdotgg/t3code/blob/main/.docs/architecture.md) | Visual system overview and event lifecycle diagrams |
| [`.docs/quick-start.md`](https://github.com/pingdotgg/t3code/blob/main/.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 install` followed by `bun run dev` to start the development environment on ports 5173 (web) and 3773 (server).
- Use `bun run dev:desktop` for Electron development and `bun run dist:desktop:dmg` to build macOS installers.
- The architecture separates concerns into **Browser** ([`wsTransport.ts`](https://github.com/pingdotgg/t3code/blob/main/wsTransport.ts)), **Server** ([`wsServer.ts`](https://github.com/pingdotgg/t3code/blob/main/wsServer.ts), [`ProviderService.ts`](https://github.com/pingdotgg/t3code/blob/main/ProviderService.ts)), and **Provider Runtime** ([`codexAppServerManager.ts`](https://github.com/pingdotgg/t3code/blob/main/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`](https://github.com/pingdotgg/t3code/blob/main/.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:

```bash
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`.