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

> Discover the t3code development workflow: bootstrap with bun install, launch dev servers, and iterate efficiently with Vitest, linting, and type checking. Get started building with Bun and TurboRepo today.

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

---

**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:

```bash
bun install .

```

The root [`package.json`](https://github.com/pingdotgg/t3code/blob/main/package.json) defines the monorepo structure and a **dependency catalog** that pins shared versions across workspaces:

```json
{
  "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)](https://github.com/pingdotgg/t3code/blob/main/package.json)

## Running the t3code Development Server

All development modes route through [`scripts/dev-runner.ts`](https://github.com/pingdotgg/t3code/blob/main/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)](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:

```bash

# 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:

```bash

# 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`](https://github.com/pingdotgg/t3code/blob/main/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)](https://github.com/pingdotgg/t3code/blob/main/apps/server/src/cli.ts#L1249-L1329)

```bash

# 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`](https://github.com/pingdotgg/t3code/blob/main/AGENTS.md) policy enforces four quality gates before submission:

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