Canticolo is a chord chart app for guitarists, pianists, recorder players, mandolin players, and harmonica players — a browser-based tool that brings together song editing, music theory, and performance into one focused workspace.
Live at canticolo.com
Most chord chart tools are either too simple (just a text file) or too complex (full notation editors). Canticolo targets the middle ground: a clean, fast app where a working musician can write a song with ChordPro syntax, explore theory without switching tabs, and pull up the chart on stage with auto-scroll and transpose. Everything syncs to the cloud and can be shared with a single link.
- ChordPro editor — Section-based editing (Verse, Chorus, Bridge, etc.) with color-coded sections, inline chord suggestions based on the active key, and a live chart preview. Supports a Chord Grid mode for measure-based progressions and a per-song strum pattern editor.
- Perform mode — Full-screen chart view with transpose, adjustable font size, multi-column layout, auto-scroll, and print (black-on-white, controls hidden).
- Five instrument modules — Guitar (6-string standard tuning, fretboard visualizer, barre/open voicings), Piano (88-key keyboard view, root-position and inversion voicings), Soprano Recorder (fingering charts with clickable diagrams that play the note — parents of school-age children especially welcome; a Survival Guide is included), Mandolin (GDAE fifths tuning, movable chord shapes, interactive fretboard), and Harmonica (10-hole Richter tuning, blow/draw layout, cross-harp position reference). An instrument adapter pattern makes all five instruments first-class; adding a sixth means implementing one interface.
- Chord analysis — Roman numeral analysis, intervals, chord tones, and optional audio playback via Tone.js for any chord in the editor.
- Theory sandbox — Key and scale explorer showing diatonic chords and common progressions. Any progression can be sent directly into a new song.
- Chord Explorer and Circle of Fifths — Interactive tools for exploring chord voicings and key relationships.
- Cloud sync and public sharing — Firebase Auth (Google + email/password), a per-user Firestore songbook with real-time sync, and one-click publish to a shareable read-only URL (
/s/{songId}). - Export — Songs exportable as
.txtor.choprofiles.
| Layer | Technology |
|---|---|
| Framework | React 19, TypeScript 5.9 |
| Build | Vite 7 |
| Styling | Tailwind CSS 4 |
| Auth / Database / Hosting | Firebase (Auth, Firestore, Hosting) |
| Audio | Tone.js |
| Testing | Vitest |
No backend server — the app is a client-only SPA. Firebase handles auth, data, and hosting.
Instrument adapter pattern. All five instruments (guitar, piano, recorder, mandolin, harmonica) implement a shared InstrumentAdapter interface (src/lib/instrument.ts). Voicings, diagrams, instrument views, and resources are all encapsulated per-instrument. Adding a new instrument means implementing one interface, with no changes to the rest of the app.
Music theory engine. The theory layer (src/lib/music-theory.ts) is instrument-agnostic: 12-tone chromatic system, 9 scale types, 20 chord qualities, diatonic harmonization for 6 scale variants, 17 common progressions with intelligent pairing suggestions, and full Roman numeral analysis. A complete audit and developer reference is in docs/theory-foundations.md.
No React Router. Navigation is a single view state in App.tsx. The one true route — /s/{songId} for public charts — is handled at the root before auth kicks in. All toolbox views (theory sandbox, chord explorer, circle of fifths, instrument views) are publicly accessible without an account; only the songbook and editor require sign-in.
No global state library. State lives at the lowest common ancestor inside AppShell. Firestore onSnapshot subscriptions provide real-time sync. Optimistic updates (create/delete) keep the UI responsive without a cache layer.
Draft recovery via localStorage. Every edit is written to localStorage before the 800ms debounced Firestore save. If a tab closes mid-edit, the draft is recovered on next open and cleared after a successful save.
Code splitting. Firebase and Tone.js are split into separate Vite chunks so the initial load stays fast even though both libraries are large.
| File | Contents |
|---|---|
docs/ARCHITECTURE.md |
System design, component tree, data model, Firestore schema, build pipeline |
docs/FEATURES.md |
User-facing feature catalog |
docs/UI_UX_SPEC.md |
Design tokens, layout system, component inventory, screen specs |
docs/theory-foundations.md |
Music theory engine reference |