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:
- Port Offset Resolution: The
resolveOffsetfunction (lines 79-104) derives an offset fromT3CODE_PORT_OFFSETor hashesT3CODE_DEV_INSTANCEto prevent collisions. - Environment Construction:
createDevRunnerEnv(lines 33-74) mapsT3CODE_PORT,VITE_DEV_SERVER_URL, and other runtime values intoprocess.env. - Turbo Invocation: Executes
turbo runwith 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 acrossapps/*andpackages/*. - Run deterministic dev servers via
node scripts/dev-runner.tswith modesdev,dev:server,dev:web, ordev:desktop. - Configure isolated instances using
T3CODE_DEV_INSTANCEorT3CODE_PORT_OFFSETto prevent port collisions. - Test changes with
bun run testand enforce quality viabun fmt,bun lint, andbun typecheckas defined inAGENTS.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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →