Development Workflow for t3code: A Complete Guide to Building with Bun and TurboRepo

The t3code development workflow consists of three deterministic stages: bootstrap with bun install ., launch dev servers via node scripts/dev-runner.ts, and iterate using Vitest, linting, and type checking against the AGENTS.md policy.

The development workflow for t3code is optimized for the Effect-TS ecosystem and Bun runtime. As a monorepo managed by TurboRepo, t3code enforces deterministic port allocation, shared dependency catalogs, and scripted orchestration to ensure consistent local development across backend, web, and desktop targets.

Bootstrap Your t3code Development Environment

Start by installing the Bun runtime (recommended version ≥1.3.11). Then initialize the workspace:

bun install .

The root package.json defines the monorepo structure and a dependency catalog that pins shared versions across workspaces:

{
  "workspaces": { "packages": ["apps/*","packages/*","scripts"] },
  "catalog": { "effect": "4.0.0-beta.45", "typescript": "^5.7.3" }
}

Source: [package.json](https://github.com/pingdotgg/t3code/blob/main/package.json)

Running the t3code Development Server

All development modes route through scripts/dev-runner.ts, which computes environment variables and delegates to Turbo.

Understanding the Dev Runner Script

The runner performs four deterministic steps before launching Turbo:

  1. Port Offset Resolution: The resolveOffset function (lines 79-104) derives an offset from T3CODE_PORT_OFFSET or hashes T3CODE_DEV_INSTANCE to prevent collisions.
  2. Environment Construction: createDevRunnerEnv (lines 33-74) maps T3CODE_PORT, VITE_DEV_SERVER_URL, and other runtime values into process.env.
  3. Turbo Invocation: Executes turbo run with filtered packages based on the selected mode.

Source: [scripts/dev-runner.ts](https://github.com/pingdotgg/t3code/blob/main/scripts/dev-runner.ts)

Available Dev Modes

Execute the runner with one of four modes to target specific packages:


# Full stack (backend + web UI)

node scripts/dev-runner.ts dev

# Backend only

node scripts/dev-runner.ts dev:server

# Web UI only

node scripts/dev-runner.ts dev:web

# Desktop app + web UI (uses loopback host)

node scripts/dev-runner.ts dev:desktop

Pass --dry-run to preview resolved ports and environment variables without launching Turbo.

Deterministic Port Configuration

Avoid collisions when running multiple instances by setting environment variables before invocation:


# Use a named instance (hashed to port offset)

export T3CODE_DEV_INSTANCE=feature-branch-xyz
node scripts/dev-runner.ts dev

# Or manually specify offset

export T3CODE_PORT_OFFSET=100
node scripts/dev-runner.ts dev

The runner exports T3CODE_PORT (backend) and VITE_DEV_SERVER_URL (frontend) so that both processes agree on networking boundaries.

Alternative Server Entry Points

For production-like scenarios, use the native CLI in apps/server/src/cli.ts. It exposes t3 start and t3 serve subcommands that invoke resolveServerConfig and runServer internally.

Source: [apps/server/src/cli.ts](https://github.com/pingdotgg/t3code/blob/main/apps/server/src/cli.ts#L1249-L1329)


# Start server and auto-open browser

bun run dev:server

# Headless mode (prints pairing URL, no browser)

node scripts/dev-runner.ts serve --dry-run

Testing and Quality Assurance in t3code

The AGENTS.md policy enforces four quality gates before submission:

bun run test   # Vitest unit/integration tests

bun fmt        # Code formatting

bun lint       # Linting

bun typecheck  # TypeScript type checking

Source: [AGENTS.md](https://github.com/pingdotgg/t3code/blob/main/AGENTS.md)

Frontend Development with Vite and React

The web UI (apps/web) runs on Vite with standard React Hot Module Replacement (HMR). While the dev runner is active, files are watched and the browser refreshes automatically.

Source: [apps/web/vite.config.ts](https://github.com/pingdotgg/t3code/blob/main/apps/web/vite.config.ts)

Summary

  • Bootstrap the monorepo with bun install . to install catalog-pinned dependencies across apps/* and packages/*.
  • Run deterministic dev servers via node scripts/dev-runner.ts with modes dev, dev:server, dev:web, or dev:desktop.
  • Configure isolated instances using T3CODE_DEV_INSTANCE or T3CODE_PORT_OFFSET to prevent port collisions.
  • Test changes with bun run test and enforce quality via bun fmt, bun lint, and bun typecheck as defined in AGENTS.md.

Frequently Asked Questions

How do I avoid port conflicts when running multiple t3code instances?

Set the T3CODE_DEV_INSTANCE environment variable to a unique string (e.g., export T3CODE_DEV_INSTANCE=feature-xyz). The resolveOffset function in scripts/dev-runner.ts hashes this value to compute a deterministic port offset, ensuring the backend and Vite dev server use non-colliding ports.

What is the difference between dev:server and serve commands?

dev:server (via scripts/dev-runner.ts) launches the server in watch mode with environment variables computed by createDevRunnerEnv, ideal for active development. serve (native to apps/server/src/cli.ts) runs the production-like CLI entry point that invokes runServer directly, typically used for headless demonstrations or when --dry-run is passed to preview configuration without starting Turbo.

How do I run tests in the t3code monorepo?

Execute bun run test from the repository root. This invokes Vitest to run unit and integration tests located alongside source files in apps/* and packages/*. The AGENTS.md policy also requires running bun fmt, bun lint, and bun typecheck before submitting changes.

Where are the port and environment configurations calculated?

All port logic resides in scripts/dev-runner.ts. The resolveOffset function (lines 79-104) determines the numeric offset, while createDevRunnerEnv (lines 33-74) assembles the final environment map including T3CODE_PORT, VITE_DEV_SERVER_URL, and VITE_WS_URL. These values are injected before Turbo launches the selected packages.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →