How to Set Up a Development Environment for t3code: Complete Guide
You can set up a t3code development environment by installing Bun ≥1.3.11 and Node ≥24.13.1, authenticating a provider (Codex or Claude Code), cloning the repository, running bun install ., and executing bun run dev to start the WebSocket server and React UI.
t3code is a monorepo that runs a Node.js WebSocket server wrapping the Codex app-server and serves a React + Vite UI. The repository uses Bun as the primary package manager and organizes code into apps/* and packages/* workspaces. This guide walks you through preparing your machine, installing dependencies, and launching the various development modes.
Prerequisites
Required Tools
You need Bun ≥1.3.11 as the primary runtime and package manager, and Node ≥24.13.1 for Effect platform libraries that run on Node.
# Install Bun
curl -fsSL https://bun.sh/install | bash
# Install Node (using nvm or official installer)
nvm install 24.13.1
Optional Tools
mise provides deterministic tool versions across environments. If you choose to use it, run mise install after cloning to install the exact versions defined in .mise.toml.
# Install mise (optional)
# Follow instructions at https://mise.jdx.dev/
Provider Authentication
t3code requires at least one AI provider to be authenticated before it can start a session. You must install and log in to either Codex CLI or Claude Code.
# Option 1: Codex CLI
npm i -g codex
codex login
# Option 2: Claude Code
claude auth login
Note: The repository's
README.mdexplicitly warns that you must have a provider installed and authenticated before running the app.
Repository Setup
Clone the repository and navigate to the project root.
git clone https://github.com/pingdotgg/t3code.git
cd t3code
Install dependencies using your chosen tools.
# Optional: Install exact tool versions with mise
mise install
# Install all workspace packages with Bun
bun install .
bun install . reads the monorepo's package.json, which defines workspaces under apps/* and packages/*, and installs the exact versions listed in the catalog section (e.g., @effect/*, vitest, typescript).
Launching Development Mode
Full Development Mode
Run the complete stack with hot-reload for the Web UI.
bun run dev
What happens: scripts/dev-runner.ts parses the dev mode, resolves a deterministic port offset, sets up environment variables (T3CODE_HOME, PORT, VITE_DEV_SERVER_URL, etc.), and invokes Turbo with filters for @t3tools/contracts, @t3tools/web, and t3. The web UI becomes available at http://localhost:5733 (or another port if T3CODE_PORT_OFFSET is set).
Desktop Development
Run the Electron desktop application alongside the web UI.
bun run dev:desktop
What changes: This runs the desktop workspace (--filter=@t3tools/desktop) together with the web UI (--filter=@t3tools/web). It uses a loopback address (127.0.0.1) for the Electron backend.
Server-Only Development
Start only the Node.js WebSocket server without the UI.
bun run dev:server
Use this mode for integration tests or when connecting a custom client.
Custom Port Configuration
Avoid port collisions when running multiple instances by setting environment variables before launching.
# Fixed numeric offset
T3CODE_PORT_OFFSET=200 bun run dev
# Or a string that hashes to an offset
T3CODE_DEV_INSTANCE=my-feature-branch bun run dev
The offset logic lives in resolveOffset inside scripts/dev-runner.ts.
Production Build (Optional)
Compile all workspaces for production deployment.
bun run build
Run the built server:
bun run start
For distributable desktop artifacts:
bun run dist:desktop:dmg # macOS DMG (arm64 by default)
See scripts/build-desktop-artifact.ts for the full command list.
Understanding the Architecture
Knowing how the pieces fit together helps you debug issues and extend the system.
- Monorepo layout –
apps/server,apps/web, andapps/desktopcontain distinct runtimes; shared contracts live inpackages/contractsand utilities inpackages/shared. - Server side – The Node.js server (
apps/server) wraps the Codex app-server (JSON-RPC over stdio). It orchestrates provider sessions, pushes ordered events viaServerPushBus, and waits for startup readiness before accepting WebSocket connections. - Web client – The React app (
apps/web) connects via a typed WebSocket transport (WsTransport) and consumes the push-based protocol defined inpackages/contracts/src/ws.ts. - Dev-runner – Located at
scripts/dev-runner.ts, this script centralizes deterministic port selection and environment construction. It ensures that every dev mode (web, server, desktop) shares a consistent configuration, making hot-reload and parallel workspaces reliable.
Summary
- Install Bun ≥1.3.11 and Node ≥24.13.1, then authenticate with Codex CLI or Claude Code.
- Clone the repository, run
mise install(optional), and executebun install .to install workspace dependencies. - Launch development modes using
bun run dev(full stack),bun run dev:desktop(Electron), orbun run dev:server(API only). - Configure
T3CODE_PORT_OFFSETorT3CODE_DEV_INSTANCEto avoid port collisions when running multiple instances. - Use
bun run buildandbun run startfor production builds, and refer toscripts/dev-runner.tsfor environment orchestration logic.
Frequently Asked Questions
What is the minimum Node.js version required for t3code?
You need Node.js ≥24.13.1 to run t3code. This version is required by some Effect platform libraries that run on Node. While Bun is the primary runtime, Node is still necessary for specific dependencies.
Why does t3code require a provider authentication before starting?
t3code wraps the Codex app-server (or Claude Code) as its AI backend. The server cannot start a session without an authenticated provider because it relies on the JSON-RPC interface over stdio to orchestrate provider sessions. You must run codex login or claude auth login before launching the app.
How do I run multiple instances of t3code without port conflicts?
Set the T3CODE_PORT_OFFSET environment variable to a numeric value (e.g., 200) or use T3CODE_DEV_INSTANCE with a string identifier (e.g., my-feature-branch). The resolveOffset function in scripts/dev-runner.ts calculates deterministic ports based on these values, ensuring each instance uses unique ports for the WebSocket server and Vite dev server.
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 →