You are helping build a full-stack web application using React + Express + SQLite.
Current state: Local development prototype. No cloud deployment, no authentication, no external integrations.
- Monorepo at
app/with npm workspaces:backend/andfrontend/ - Backend: Express.js + better-sqlite3, runs on port 3001
- Frontend: React + Vite, runs on port 5173 (proxies API to 3001)
- Database: SQLite file at
backend/app.db
Always use npm scripts from the app/ directory. Never run node commands directly.
cd app
# Seed/reset the database
npm run seed
# Start both backend + frontend (uses concurrently)
npm run devBackground terminal one-liners (ensures Node.js is on PATH):
Windows (PowerShell):
cd "<WORKSPACE_ROOT>\app"; $env:Path = "$env:ProgramFiles\nodejs;$env:SystemRoot\System32;$env:SystemRoot;" + $env:Path; npm run devmacOS / Linux (Bash):
cd "<WORKSPACE_ROOT>/app" && export PATH="/usr/local/bin:/opt/homebrew/bin:$PATH" && npm run devThere are also helper scripts: start-dev.ps1 (Windows) and start-dev.sh (macOS/Linux).
- Use
npm run devto start servers — nevernode src/index.jsornpx node. - Use
npm run seedto seed the database — nevernode backend/src/seed.js. - Kill port 3001 before starting if it's already in use:
- Windows:
Get-NetTCPConnection -LocalPort 3001 | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue } - macOS/Linux:
lsof -ti:3001 | xargs kill -9 2>/dev/null
- Windows:
- The PATH in background terminals may not include Node.js. Fix per OS:
- Windows:
$env:Path = "$env:ProgramFiles\nodejs;$env:SystemRoot\System32;" + $env:Path - macOS/Linux:
export PATH="/usr/local/bin:/opt/homebrew/bin:$PATH"
- Windows:
- Do not use
npx node— it downloads a different Node.js version that breaks native modules (better-sqlite3). - After schema or seed changes, always re-seed before testing.
- Do NOT spawn duplicate servers. Vite (frontend) has Hot Module Replacement and the backend uses
node --watch— code changes reflect automatically. Only restart after re-seeding the database. - Kill ALL stale servers before starting new ones — check ports 3001 + 5173–5175:
- Windows:
Get-NetTCPConnection -LocalPort 3001,5173,5174,5175 -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }
- macOS/Linux:
lsof -ti:3001,5173,5174,5175 | xargs kill -9 2>/dev/null
- Windows:
- ES Modules throughout (
"type": "module"in both package.json files); useimport/export, notrequire - No TypeScript yet (plain
.jsbackend,.jsxfrontend) - React functional components with hooks; no class components
- SQL queries written inline in route handlers (no query builder or ORM)
- CSS custom properties for theming in
styles/tokens.css; no CSS-in-JS or Tailwind - Component-scoped CSS files (e.g.
HomePage.cssalongsideHomePage.jsx)
Each route file:
- Imports
dbfrom../db.js(synchronous better-sqlite3) - Uses
db.prepare().all()/.get()/.run() - Returns JSON via
res.json() - Is mounted in
index.jsunder/api
- Routing:
App.jsxdefines all<Route>elements - API layer:
frontend/src/api/index.js— thinfetchJSONwrapper; all functions return promises - Styling: design tokens in
styles/tokens.css(CSS custom properties), component-scoped CSS - Pages: one file per page in
pages/, with matching.cssfile