How to Test t3code Locally: Complete Guide for the Monorepo
Use bun run test to execute the full Vitest suite across all workspaces, or target specific apps with --filter flags for faster feedback loops.
Testing t3code locally requires understanding its monorepo architecture, which combines a Node WebSocket server, a React frontend, and a Codex app-server runtime. The repository uses Vitest as its test runner (invoked via the bun task runner) and provides a dev-runner utility to manage deterministic ports and environment variables. This guide covers how to execute the complete test matrix, from SQLite-backed server tests to Playwright-driven browser component tests.
Prerequisites and Setup
Install Dependencies
Before running any tests, install the workspace dependencies using the catalog defined in the root package.json. This ensures all Effect dependencies and workspace links are resolved correctly.
bun install
Running the Test Suite
Full Test Suite with Vitest
The root vitest.config.ts defines a global configuration that includes a module-resolution alias pointing to the contracts package. This ensures type-safe push envelopes are validated across all workspaces.
bun run test
This command executes Vitest across every workspace (apps/*, packages/*), running unit, integration, and browser tests where configured.
Server-Side Tests (SQLite and Git Integration)
Server tests in apps/server/vitest.config.ts explicitly disable parallel execution because they manipulate SQLite files, real Git worktrees, and other stateful resources that would flake under concurrent runs.
bun run test --filter apps/server
Key configuration in apps/server/vitest.config.ts:
fileParallelism: false– ensures sequential execution to prevent SQLite lock conflicts.
Web Application Tests
For rapid feedback on frontend logic without browser overhead, run the web unit tests directly:
bun run test --filter apps/web
Browser Component Tests with Playwright
The web workspace includes apps/web/vitest.browser.config.ts, which spins up a Vite dev server and runs Playwright-based component tests inside a headless Chromium instance.
bun run test --filter apps/web --include src/components/**/*.browser.tsx
Desktop Smoke Tests
To verify the full Electron stack and the bridge between the Node backend and the desktop shell, run the desktop smoke test:
bun run test:desktop-smoke
This builds the Electron app and launches a short-lived instance to ensure the artifact runs correctly.
Development Mode Validation
Using the dev-runner Script
The dev-runner (scripts/dev-runner.ts) is a CLI utility that resolves deterministic ports, builds the appropriate environment (T3CODE_* variables), and invokes Turbo to start the selected subset of packages.
To verify the configuration without launching processes:
node scripts/dev-runner.ts dev --dry-run
To start the development stack with the same environment used by the test harness:
node scripts/dev-runner.ts dev
Deterministic Port Allocation
The dev-runner computes unique port offsets from either T3CODE_DEV_INSTANCE or a numeric T3CODE_PORT_OFFSET. It verifies availability on a list of loopback interfaces to prevent "address already in use" failures when running multiple dev instances or CI jobs in parallel.
Understanding the Test Architecture
The ServerPushBus (exercised in apps/server/src/wsServer/pushBus.test.ts) delivers events in a guaranteed order, which both production and tests rely on. The bus implementation is guaranteed by the single-threaded worker model.
Integration tests utilize DrainableWorker from packages/shared/src/DrainableWorker.ts to create deterministic, queue-backed workers for async validation.
The typed WebSocket contracts in packages/contracts/src/ws.ts ensure that both server and client tests validate the same message schemas.
Summary
- Use
bun run testto execute the complete Vitest suite across all monorepo workspaces. - Target specific apps with
--filter apps/serveror--filter apps/webfor faster feedback on isolated changes. - Run browser tests via
apps/web/vitest.browser.config.tsusing Playwright in headless Chromium. - Validate desktop builds with
bun run test:desktop-smokebefore releasing the Electron artifact. - Leverage
scripts/dev-runner.tswith--dry-runto debug port allocation and environment variables without spawning processes. - Note that server tests disable
fileParallelismto prevent SQLite and Git worktree conflicts.
Frequently Asked Questions
What is the fastest way to test t3code locally?
Run bun run test --filter apps/server for the server-side logic or bun run test --filter apps/web for frontend unit tests. These commands skip the browser and desktop smoke tests, providing feedback in seconds rather than minutes.
Why do server tests run with fileParallelism disabled?
The apps/server/vitest.config.ts explicitly sets fileParallelism: false because the test suite manipulates SQLite databases and real Git worktrees. Running these tests in parallel would cause file-lock conflicts and flaky failures due to concurrent disk access.
How does t3code handle port conflicts during local testing?
The scripts/dev-runner.ts utility calculates deterministic port offsets using the T3CODE_DEV_INSTANCE or T3CODE_PORT_OFFSET environment variables. It scans loopback interfaces to verify availability before binding, ensuring that multiple developers or CI runners can execute tests simultaneously without "address already in use" errors.
Can I run browser tests without installing additional dependencies?
No, the browser tests in apps/web/vitest.browser.config.ts require Playwright and a headless Chromium instance. You must install these dependencies (typically via bun install which handles the Playwright browsers) before running the component tests.
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 →