# How to Test t3code Locally: Complete Guide for the Monorepo

> Easily test t3code locally using Vitest. Run the full suite or filter by app for quick feedback in your monorepo. Follow our complete guide to get started.

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

---

**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`](https://github.com/pingdotgg/t3code/blob/main/package.json). This ensures all Effect dependencies and workspace links are resolved correctly.

```bash
bun install

```

## Running the Test Suite

### Full Test Suite with Vitest

The root [`vitest.config.ts`](https://github.com/pingdotgg/t3code/blob/main/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.

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

```bash
bun run test --filter apps/server

```

Key configuration in [`apps/server/vitest.config.ts`](https://github.com/pingdotgg/t3code/blob/main/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:

```bash
bun run test --filter apps/web

```

### Browser Component Tests with Playwright

The web workspace includes [`apps/web/vitest.browser.config.ts`](https://github.com/pingdotgg/t3code/blob/main/apps/web/vitest.browser.config.ts), which spins up a Vite dev server and runs Playwright-based component tests inside a headless Chromium instance.

```bash
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:

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

```bash
node scripts/dev-runner.ts dev --dry-run

```

To start the development stack with the same environment used by the test harness:

```bash
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`](https://github.com/pingdotgg/t3code/blob/main/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`](https://github.com/pingdotgg/t3code/blob/main/packages/shared/src/DrainableWorker.ts) to create deterministic, queue-backed workers for async validation.

The typed WebSocket contracts in [`packages/contracts/src/ws.ts`](https://github.com/pingdotgg/t3code/blob/main/packages/contracts/src/ws.ts) ensure that both server and client tests validate the same message schemas.

## Summary

- **Use `bun run test`** to execute the complete Vitest suite across all monorepo workspaces.
- **Target specific apps** with `--filter apps/server` or `--filter apps/web` for faster feedback on isolated changes.
- **Run browser tests** via [`apps/web/vitest.browser.config.ts`](https://github.com/pingdotgg/t3code/blob/main/apps/web/vitest.browser.config.ts) using Playwright in headless Chromium.
- **Validate desktop builds** with `bun run test:desktop-smoke` before releasing the Electron artifact.
- **Leverage [`scripts/dev-runner.ts`](https://github.com/pingdotgg/t3code/blob/main/scripts/dev-runner.ts)** with `--dry-run` to debug port allocation and environment variables without spawning processes.
- **Note that server tests** disable `fileParallelism` to 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`](https://github.com/pingdotgg/t3code/blob/main/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`](https://github.com/pingdotgg/t3code/blob/main/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`](https://github.com/pingdotgg/t3code/blob/main/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.