A local-first practice system for rock / metal / progressive guitar and bass, built from the validated design (the reference mockups in ../Frets-Mockups.html show the original five screens; the app has since grown to nine).
Stack: Next.js (frontend) + Node/Express (backend), TypeScript throughout. See ARCHITECTURE.md for the security-reviewed version pins and rationale.
frets-app/
├─ server/ # Node + Express 5 API + the theory engine (TypeScript)
├─ web/ # Next.js 16 App Router frontend (nine screens)
└─ ARCHITECTURE.md
- Node.js 24 LTS recommended (works on ≥ 20.9). Check:
node -v. - npm (bundled with Node).
npm run setup # first time only: installs server/ and web/ deps
npm start # builds the static web app, serves everything on one portOpen http://localhost:4000 — the app and the API share one origin, so
there is nothing else to start. npm start rebuilds the frontend on every
launch; npm run serve skips the build when nothing changed. From the
browser menu you can install Frets as an app (PWA): the shell keeps opening
offline, and live data (drills, progress) needs the server — pages fall back
to their offline/error states when it is down. The service worker never
caches /api, so progress is never stale.
A zero-dependency launcher does install → build → serve in one step, on any port:
npx . # from a clone/tarball: setup (first run), build, serve on :4000
node bin/frets.mjs --port 5000 # same thing, a different port
node bin/frets.mjs --no-build # skip the rebuild when web/out is currentIt resolves its own location, so it works from any directory. The package keeps
"private": true — to enable a bare npx frets for others, drop that flag
and npm publish from your own account (a manual, owner-only step).
1) Backend API — port 4000
cd server
npm install
npm run dev # http://127.0.0.1:4000 (Frets API)2) Frontend — port 3000
cd web
npm install
npm run dev # http://localhost:3000 (3001 also works if 3000 is taken — CORS allows both)Open http://localhost:3000. The dev frontend calls the API at http://localhost:4000
(override with NEXT_PUBLIC_API if needed). The packaged build instead inlines
a same-origin API base at export time (FRETS_PACKAGED=1).
- root:
npm start(one-port packaged build at http://localhost:4000),npm run setup,npm run serve(skip rebuild),npm run smoke:packaged(packaged-mode smoke on a scratch port),npm test,npm run e2e. server:npm run dev(watch),npm start,npm run typecheck,npm test(vitest: engine + API tests incl. the exhaustive tuning×scale×root accuracy matrix),npm run test:watch,npm run test:selfcheck(standalone engine self-check).- Key API surface:
/api/exercise(all drill kinds/modes, steps enriched with true pitch),/api/exercise-midi(the same drill as a Standard MIDI File for your DAW),/api/note-map(octave-labeled note finder),/api/progress(streak, lock-ins, mastery stats, spaced-recall schedule, per-drill tempos). web:npm run dev,npm run build,npm start,npm run typecheck,npm run e2e(Playwright end-to-end tests for all nine screens — Today, Daily Session, Fretboard Lab, Song Workbench, Writing Bench, Jam, The Rig, Mastery, Ear Training — plus the exercise/lead players; reuses the running dev servers or starts them).
- Theory engine (
server/src/theory/): pitch-class math, scale/mode definitions, fretboard mapping (degree / note / function views), and the Writing Bench (ranked next-chords + note-function classification), all pure and unit-checked (npm test). - Exercise engine (
server/src/theory/exercise.ts,GET /api/exercise): generates concrete, playable drills with real tab + alternate-pick directions + tempo timing, for any instrument/tuning/scale/chord —- scale runs: box positions (moveable up the neck), whole-neck, 3 notes per string, diagonal connect-the-positions (climbs the whole neck), and single-string walks;
- the chromatic 1-2-3-4 spider warm-up;
- chord arpeggios (
kind=arpeggio): box and sweep shapes (maj/min/dom7/power). All pure pedagogy generated from theory — never copyrighted tab. Accuracy is guarded by a property-based matrix test (matrix.test.ts: the fret↔note law + degree labels across every tuning × scale × root × generator).
- Content (
server/src/data/): a catalog of common guitar/bass tunings (standard, drop, open, 7/8-string, 4–6-string bass), tone presets described by pedal/amp type (not specific brands), style/technique song templates (Ultimate-Guitar search links only — never embedded tab), and three curriculum tracks (Modern metal · Blues/classic rock · Bass groove bootcamp), each 3 weeks × 6 days. The content stays neutral to any one player's taste or gear. - Screens (
web/app/, nine): Today, Daily Session (phase timer + a playable drill per phase, with a keyboard-driven Stage Mode for play-time), Fretboard Lab (degree/note/function toggle, chord overlay, a "Drill this scale" player with every exercise type + metronome), Song Workbench, Writing Bench (chord moves + function-colored board + a Lead Composer: place notes over a chord chain with hammer/pull/slide/bend articulations, drum overlay, MIDI), Jam (vamp/backing loops with the scale lit), The Rig (tuning comparison + transfer badges + a custom-tuning builder), Mastery (spaced-repetition note quiz), Ear Training. - More engines: Riff Forge (deterministic pedal-tone riffs from a 2–4 chord chain), a drum-groove locker (11 grooves), harmonized leads, capo + left-handed mirror, and Standard-MIDI export across drills, riffs, vamps, and leads.
- Progress persists to
server/data/progress.json(created on first write). Back it up by copying that one file, or use Save a backup / Restore on the Today page.
- Pinned: Next.js ~16.2.6 (past CVE-2025-29927 and the May 2026 13-advisory release), React 19.x (patched for the Dec 2025 RSC RCE), Express ^5.2.1 (ReDoS-resistant routing), Node 24 LTS.
- Minimal dependencies (express, cors, zod). No database driver, no auth/session library, no file-upload parser (avoids the May 2026
multipartyDoS). - CORS restricted to
localhost:3000; backend binds to127.0.0.1; all inputs validated with zod; nodangerouslySetInnerHTML. - Run
npm auditafter install; target is zero high/critical.
- We never embed copyrighted tablature. Song entries link out to an Ultimate-Guitar search for the tab.
- The Writing Bench's chord suggestions and note-function colors are computed live for any key/tuning, so the low-G 7-string Drop C (low G) (G minor) and Drop C (D minor) examples both work out of the box.