Development Setup
This guide covers everything you need to start developing Gerbtrace locally.
Prerequisites
- Node.js 24.18.0 (LTS) — pinned via
.nvmrc; runnvm usein the repo root - pnpm 10 or later (recommended via Corepack:
corepack enable pnpm) - Rust (only required for desktop app development)
Getting started
# Clone the repository (with the package-renderer submodule)
git clone --recurse-submodules https://github.com/newmatik/gerbtrace.git
cd gerbtrace
# Select the pinned Node version from .nvmrc
nvm use
# Install dependencies
pnpm install
# Start the web development server
pnpm run dev
Submodule note: Gerbtrace vendors the package-renderer package as a git submodule. If you cloned without --recurse-submodules, or you pulled changes that added or updated the submodule, initialize it before running pnpm install — otherwise typecheck, dev, and build fail with missing package-renderer/src/* modules:
git submodule update --init --recursive
If pnpm is not found, install Corepack and enable it, then run pnpm install again:
# Install corepack
npm install --global corepack@latest
# Enable corepack
corepack enable pnpm
# Install dependencies
pnpm install
# Start the web development server again
pnpm run dev
Visit http://localhost:3000 in your browser.
Environment variables
Create a .env file in the project root for Supabase connection:
SUPABASE_URL=<your-supabase-url>
SUPABASE_ANON_KEY=<your-supabase-anon-key>
For local-only development (no team features), these can be omitted. Local projects use IndexedDB and do not require a backend.
Local Supabase development
You can run Supabase locally (Docker + CLI) and point the app at it via .env.
Prerequisites: Docker (required for supabase start), Node/pnpm (already in the repo).
Start local stack:
pnpm supabase:start
The first run can take a few minutes while images are pulled.
Get local keys: After start, the CLI prints API URL, anon key, and service_role key. You can also run pnpm exec supabase status. No project linking is needed for a purely local project.
Configure the app: Copy .env.example to .env and set:
SUPABASE_URL=http://127.0.0.1:54321SUPABASE_ANON_KEY=<anon key from start/status>SUPABASE_SECRET_KEY=<service_role key from start/status>(for server APIs and admin usage)
Apply schema and seed:
pnpm supabase:reset
This applies all migrations and runs the seed. pnpm supabase:migrate pushes pending migrations to the local database without reseeding.
Seed data: The seed creates test users, a team "Gerbtrace Dev" (slug gerbtrace-dev), and a project "Sample PCB". Log in at /auth/login with Email & Password: admin@gerbtrace.local / Password123 (team admin and platform admin), editor@gerbtrace.local / Password123 (editor), or viewer@gerbtrace.local / Password123 (viewer).
Platform-admin access is stored in profiles.is_super_admin; it is independent of team roles and is never configured through an environment variable. Browser sessions cannot update this field. Grant or revoke it only through a trusted service-role or database operation after verifying the user UUID and environment.
Run the app: pnpm run dev (or pnpm exec nuxt dev --no-fork). Auth redirect is already http://localhost:3000/auth/callback in supabase/config.toml.
Optional — Edge Functions: For flows that call Edge Functions (e.g. send-invitation, admin-team-action, stripe-checkout), run in a second terminal: pnpm exec supabase functions serve. The app calls SUPABASE_URL/functions/v1/<name>, so with a local URL this hits the local functions server. Stripe-related functions need Stripe keys in env if you test billing; otherwise email/password and Magic Link work without them.
Optional — GitHub OAuth (local): To test GitHub login locally, set GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET in .env. supabase/config.toml already references them with env(...).
Stop: pnpm supabase:stop
Desktop development
The desktop app is built with Tauri 2. Make sure Rust is installed via rustup.
# Start Tauri development (launches native window with hot reload)
pnpm run tauri:dev
# Build desktop app for your current platform
pnpm run tauri:build
Tauri development mode runs the Nuxt dev server and opens a native window pointing to it. Changes to Vue files hot-reload in the desktop window just like in the browser.
Production build
The web app is a Cloudflare Worker, not a static site:
# Worker build (cloudflare-module preset) — what Cloudflare Workers Builds runs
pnpm run build
# Build and deploy with wrangler (needs a Cloudflare API token for the Newmatik account)
pnpm run deploy
pnpm run generate produces the static frontend in .output/public/ for the Tauri desktop bundle only. See the Release Process for deployment authority and the release checklist.
Tech stack
| Component | Technology |
|---|---|
| Framework | Nuxt 4 (SPA mode, SSR disabled) |
| UI Library | Nuxt UI 4 |
| Desktop | Tauri 2 |
| Gerber Parsing | Custom RS-274X / Excellon parser |
| Rendering | Canvas 2D |
| ZIP Handling | JSZip |
| Text Diff | diff |
| Local Storage | Dexie.js (IndexedDB) |
| Excel Parsing | xlsx |
| Virtual Scrolling | @tanstack/vue-virtual |
| Error Monitoring | Sentry |
Project structure
gerbtrace/
app/ # Nuxt app directory
components/ # Vue components
composables/ # Vue composables (state management)
pages/ # Nuxt pages (routes)
utils/ # Utility functions
workers/ # Web Workers
lib/ # Core library code
gerber/ # Gerber/drill parser and plotter
renderer/ # Canvas 2D and realistic renderers
package-renderer/ # Component package/footprint renderer (git submodule)
src-tauri/ # Tauri desktop app (Rust)
supabase/ # Database migrations and edge functions
content/ # Nuxt Content documentation
public/ # Static assets (packages, samples)
scripts/ # Build and maintenance scripts
.github/workflows/ # CI/CD workflows
Useful commands
| Command | Description |
|---|---|
pnpm run dev | Start web dev server (runs the pre-commit checks first; pnpm exec nuxt dev --no-fork skips them) |
pnpm run build | Production Worker build |
pnpm run generate | Static frontend for the desktop bundle |
pnpm run tauri:dev | Start desktop dev |
pnpm run tauri:build | Build desktop app |
pnpm run typecheck | Run TypeScript type checking |
pnpm run test | Run the Vitest suite |
pnpm run test:browser | Run the Playwright smoke suite |
pnpm run packages:manifest | Regenerate package library manifests |
pnpm run packages:check | Validate package library consistency |
pnpm run libraries:sync | Sync external CAD libraries |
pnpm run libraries:parse | Parse CAD libraries to SMD packages |
pnpm run libraries:parse:tht | Parse CAD libraries to THT packages |