ProtoPulse runs as a single Node.js process that serves both the React frontend (via Vite’s dev middleware) and the Express 5 REST API on port 5000. This guide walks through everything you need to get a local instance running from scratch.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/wtyler2505/ProtoPulse/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
Before you start, make sure you have the following installed:- Node.js 20+ — check with
node --version - PostgreSQL 14+ — check with
psql --version
Setup
Install dependencies
Configure environment variables
Copy the example file and fill in the required values:At minimum you must set Create the database and role in psql first if they don’t exist:See the Environment variables table below for all available options.
DATABASE_URL. A typical local value looks like:Push the database schema
drizzle-kit push, which introspects shared/schema.ts and applies any missing tables or column changes directly to your PostgreSQL database. No migration files are generated — this is the recommended flow for local development.Start the dev server
The dev server runs both the Vite HMR frontend and the Express 5 backend on port 5000 as a single process (
tsx server/index.ts). There is no separate frontend dev server to start — Vite is registered as Express middleware and handles all client/ requests, while Express handles /api/* routes. The npm run dev:client script starts Vite alone (useful only when running the backend separately).Environment variables
These variables are read from.env at startup. The server validates required variables on boot and will refuse to start if they are missing.
| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL | Yes | — | PostgreSQL connection string, e.g. postgresql://user:pass@host:5432/db |
API_KEY_ENCRYPTION_KEY | Production only | Random per-boot | 32-byte hex string for AES-256-GCM encryption of stored AI provider API keys. A random key is generated each boot in development, which invalidates any stored keys on restart. |
PORT | No | 5000 | Server listen port |
NODE_ENV | No | development | development | production | test |
LOG_LEVEL | No | info | error | warn | info | debug |
TRUST_PROXY | No | 0 | Number of trusted reverse-proxy hops (set to 1 behind a single proxy) |
STREAM_TIMEOUT_MS | No | 120000 | Inactivity timeout in milliseconds for SSE AI chat streams |
ADMIN_API_KEY | No | — | Shared secret for /api/admin/* and /api/backup/* maintenance routes |
DB_POOL_MAX | No | Profile default | Maximum PostgreSQL connection pool size |
CACHE_MAX | No | Profile default | Maximum entries in the server-side LRU cache |
RATE_LIMIT_MAX | No | 300 | Maximum requests per 15-minute window per IP |
DISABLE_AI_FALLBACK | No | 0 | Set to 1 to disable automatic fallback between AI providers |
PARTS_CATALOG_V2 | No | false | Set to true to enable the unified parts catalog (ADR 0010) read paths |
ARDUINO_CLI_PATH | No | PATH lookup | Absolute path to the arduino-cli binary |
ARDUINO_DATA_DIR | No | — | Arduino CLI data directory |
ARDUINO_SKETCH_ROOT | No | — | Root directory for Arduino sketch files |
NPM scripts reference
| Script | Command | Description |
|---|---|---|
npm run dev | NODE_ENV=development tsx server/index.ts | Start the development server (Express + Vite HMR) on port 5000 |
npm run dev:client | vite dev --port 5000 | Start Vite alone (no Express backend) |
npm run build | tsx scripts/build.ts | Production build — esbuild bundles the backend, Vite builds the frontend into dist/ |
npm run start | NODE_ENV=production node dist/index.cjs | Run the production build |
npm run check | tsc | TypeScript type check — must pass with zero errors before merging |
npm run db:push | drizzle-kit push | Sync shared/schema.ts to PostgreSQL (development) |
npm run db:generate | drizzle-kit generate | Generate SQL migration files from schema diff |
npm run db:migrate | drizzle-kit migrate | Apply pending SQL migrations (production) |
npm run db:studio | drizzle-kit studio | Open Drizzle Studio database browser |
npm test | vitest run | Run the full test suite across all workspace projects |
npm run test:watch | vitest | Interactive test watch mode |
npm run test:coverage | vitest run --coverage | Run tests and generate a coverage report (v8 provider) |
npm run test:e2e | playwright test | Run Playwright end-to-end tests |
npm run test:a11y | playwright test e2e/p1-a11y-scan.spec.ts | Accessibility audit via axe-core |
npm run types:generate | tsx scripts/generate-api-types.ts | Regenerate shared/api-types.generated.ts |
npm run genkit:dev | genkit start -- npm run dev | Start the dev server with the Genkit developer UI |
npm run tauri:dev | tauri dev | Start the Tauri desktop shell in development mode |
npm run tauri:build | tauri build | Build the Tauri desktop application |
Running tests
ProtoPulse uses Vitest with a workspace configuration that covers both the server and client code in separate projects.__tests__/ directories. The test suite includes unit tests for the wire router, ERC engine, constraint solver, diff engines, and all context providers.
TypeScript check
Before opening a pull request, run the TypeScript compiler in check-only mode:strictTypeChecked ESLint rules.
Linting and formatting
eslint.config.js using the flat config format with typescript-eslint, eslint-plugin-react, eslint-plugin-react-hooks, eslint-plugin-jsx-a11y, and eslint-import-resolver-typescript.