Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/pingdotgg/t3code/llms.txt

Use this file to discover all available pages before exploring further.

Overview

T3 Code uses Turbo for orchestrated builds across the monorepo. The build process produces optimized bundles for web, server, and desktop distributions.

Quick Build Commands

# Build all packages
bun run build

Build Process

Build Order

Turbo builds packages in dependency order:
1

Packages (Parallel)

  • packages/contracts (Effect/Schema → ESM/CJS)
  • packages/shared (Runtime utilities)
2

Apps (Sequential)

  • apps/web (React + Vite → static assets)
  • apps/server (Node.js → bundled ESM)
3

Desktop (Final)

  • apps/desktop (Electron → platform binaries)

Build Outputs

PackageOutput DirectoryFormat
contractsdist/ESM + CJS + types
webdist/Static HTML/JS/CSS
serverdist/Bundled ESM (index.mjs)
desktopdist-electron/Electron bundles

Building Components

Contracts Package

Builds Effect/Schema definitions to distributable format:
cd packages/contracts
bun run build
Build Tool: tsdown (TypeScript bundler) Output:
  • dist/index.mjs - ESM bundle
  • dist/index.cjs - CommonJS bundle
  • dist/index.d.ts - TypeScript declarations
Configuration:
package.json
{
  "scripts": {
    "build": "tsdown src/index.ts --format esm,cjs --dts --clean"
  }
}

Web App

Builds React application to static assets:
cd apps/web
bun run build
Build Tool: Vite 8 Output: dist/ directory with:
  • index.html - HTML entry point
  • assets/*.js - Code-split JavaScript bundles
  • assets/*.css - Extracted stylesheets
  • assets/* - Images, fonts, other assets
Optimizations:
  • React Compiler (automatic memoization)
  • Code splitting (route-based)
  • Tree shaking (unused code elimination)
  • Minification (Terser)
  • CSS optimization (Lightning CSS)
Configuration:
vite.config.ts
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    react({
      babel: {
        plugins: [['babel-plugin-react-compiler', {}]],
      },
    }),
  ],
  build: {
    outDir: 'dist',
    sourcemap: true,
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['react', 'react-dom'],
          router: ['@tanstack/react-router'],
        },
      },
    },
  },
});

Server Package

Builds Node.js backend to bundled ESM:
cd apps/server
bun run build
Build Tool: Custom bundler (scripts/cli.ts build) Output: dist/index.mjs (single bundle including web assets) Process:
  1. Builds web app (if not already built)
  2. Bundles server code with tsdown
  3. Embeds web assets in server bundle
  4. Generates CLI entry point
Configuration:
scripts/cli.ts
// Custom build script
// - Bundles TypeScript to ESM
// - Includes web dist as static assets
// - Generates shebang for CLI execution
The server build includes the web app for production serving.

Desktop App

Builds Electron application:
cd apps/desktop
bun run build
Build Tool: tsdown + Electron Output: dist-electron/ directory with:
  • main.js - Electron main process
  • preload.js - Preload scripts
For distribution, see Desktop Distribution below.

Production Build

Full Production Build

Build everything for production:
# Clean previous builds (optional)
bun run clean

# Install dependencies
bun install

# Run full build
bun run build

# Verify with typecheck
bun run typecheck

# Run tests
bun run test

Start Production Server

Run the built server:
bun run start
This runs node dist/index.mjs which:
  • Starts WebSocket server
  • Serves built web app as static files
  • Opens browser to the app
Production Configuration:
# Custom port
T3CODE_PORT=8080 bun run start

# Custom state directory
bun run start -- --state-dir ~/.t3/prod

# Don't open browser
T3CODE_NO_BROWSER=1 bun run start

Desktop Distribution

Build Desktop Artifacts

Create platform-specific installers:
# ARM64 .dmg (default)
bun run dist:desktop:dmg

# Intel .dmg
bun run dist:desktop:dmg:x64

# Specific architecture
bun run dist:desktop:dmg:arm64
Output: release/T3 Code (Alpha)-0.0.3-arm64.dmg

Custom Platform/Architecture

Build for specific targets:
bun run dist:desktop:artifact -- \
  --platform mac \
  --target dmg \
  --arch arm64
Available Options:
FlagValuesDescription
--platformmac, linux, winTarget platform
--targetdmg, AppImage, nsisInstaller format
--archarm64, x64CPU architecture

DMG Packaging Options

For debugging package contents:
bun run dist:desktop:dmg -- --keep-stage
Staging files remain in .stage/ directory.
Enable code signing (requires certificates in CI/secrets):
bun run dist:desktop:dmg -- --signed
macOS: Uses Apple Developer IDWindows: Uses Azure Trusted Signing with these environment variables:
  • AZURE_TRUSTED_SIGNING_ENDPOINT
  • AZURE_TRUSTED_SIGNING_ACCOUNT_NAME
  • AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE_NAME
  • AZURE_TRUSTED_SIGNING_PUBLISHER_NAME
  • AZURE_TENANT_ID
  • AZURE_CLIENT_ID
  • AZURE_CLIENT_SECRET

Desktop Package Contents

The desktop package includes:
  • Electron shell (dist-electron/)
  • Web UI (bundled from apps/web/dist)
  • Backend server (apps/server/dist as t3 CLI)
  • App icon (from assets/macos-icon-1024.png)
How it works:
apps/desktop/src/main/backend.ts
// Spawns bundled t3 CLI on loopback with auth token
const backend = spawn(t3BinaryPath, [
  '--auth-token', token,
  '--no-browser',
]);

// UI connects via WebSocket
const wsUrl = `ws://127.0.0.1:${port}?token=${token}`;

Build Optimization

Turbo Caching

Turbo caches build outputs for faster rebuilds:
# Check cache status
turbo run build --dry-run

# Force rebuild (skip cache)
turbo run build --force

# Clear cache
rm -rf .turbo
Cache Configuration:
turbo.json
{
  "tasks": {
    "build": {
      "outputs": ["dist/**", "dist-electron/**"],
      "dependsOn": ["^build"]
    }
  }
}

Parallel Builds

Turbo runs independent builds in parallel:
# Build with concurrency limit
turbo run build --concurrency=2

# Build specific packages
turbo run build --filter=@t3tools/web --filter=@t3tools/server

Incremental Builds

Development builds support incremental compilation:
# Watch mode (incremental)
cd packages/contracts
bun run dev  # tsdown --watch

CI/CD Integration

GitHub Actions Example

.github/workflows/build.yml
name: Build

on:
  push:
    branches: [main]
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - uses: oven-sh/setup-bun@v1
        with:
          bun-version: 1.3.9
      
      - name: Install dependencies
        run: bun install
      
      - name: Build
        run: bun run build
      
      - name: Typecheck
        run: bun run typecheck
      
      - name: Test
        run: bun run test
      
      - name: Upload server artifact
        uses: actions/upload-artifact@v3
        with:
          name: t3-server
          path: apps/server/dist/

Desktop Release Workflow

.github/workflows/release.yml
name: Release

on:
  push:
    tags:
      - 'v*'

jobs:
  build-desktop:
    strategy:
      matrix:
        os: [macos-latest, ubuntu-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: oven-sh/setup-bun@v1
      
      - name: Build desktop
        run: |
          bun install
          bun run build:desktop
      
      - name: Create installer (macOS)
        if: matrix.os == 'macos-latest'
        run: bun run dist:desktop:dmg -- --signed
        env:
          APPLE_ID: ${{ secrets.APPLE_ID }}
          APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
      
      - name: Upload to release
        uses: actions/upload-release-asset@v1
        with:
          upload_url: ${{ github.event.release.upload_url }}
          asset_path: ./release/*

Troubleshooting

Ensure all dependencies are installed:
bun run clean
bun install
bun run build
Clear the Turbo cache:
rm -rf .turbo apps/*/.turbo packages/*/.turbo
bun run build --force
Check that you’ve built the dependencies first:
bun run build:contracts
bun run build:desktop
Force rebuild the web app:
cd apps/web
rm -rf dist
bun run build

Pre-Commit Checks

Both bun lint and bun typecheck must pass before tasks are considered complete.
Run all checks before committing:
# Lint
bun run lint

# Type check
bun run typecheck

# Test
bun run test

# Build
bun run build

Automated Checks

Add to .husky/pre-commit:
#!/bin/sh
bun run lint
bun run typecheck

Next Steps

Testing

Learn about testing strategies

Setup

Review development setup

Build docs developers (and LLMs) love