Open Source Libraries We Evaluated for GuitarTechHub — and Why We Built Our Own Instead
fretboard.js, VexTab, chord-symbol, and Tonal.js looked like obvious fits for our music-theory tools — here's what we found, and why we built our own instead.
GuitarTechHub’s calculators and backing-track player lean on a fair amount of music theory — chord parsing, scale suggestions, fretboard position diagrams. Before writing any of that by hand, we went looking for existing open source libraries to lean on instead. This is what we actually found, and why most of it didn’t make the cut.
fretboard.js and chord-symbol: unmaintained, and heavier than the gap
When we built the chord-tone highlighting on the scale-suggestion fretboard diagram (the
small dot overlay that shows where to land a phrase while a backing track plays), fretboard.js
and the chord-symbol npm package both looked like natural fits — a fretboard renderer and a
chord-symbol parser are exactly the two pieces that feature needed.
Checking the actual repositories changed our minds. Both had gone quiet: fretboard.js’s last
push was March 2023, chord-symbol’s was December 2023. Neither is necessarily broken, but
neither is a bet we wanted to make for a feature we intended to keep extending. And the
dependency cost was real, not hypothetical — fretboard.js pulls in d3-selection;
chord-symbol pulls in four separate @tonaljs packages plus lodash. That’s a lot of
transitive weight for capability our own zero-dependency fretboard.ts and ScaleDiagram.tsx
already covered.
So we extended what we had instead: voicing.ts grew a chordToneIntervals() function,
fretboardPositionsForScale() took an options object instead of four positional parameters
and started returning an isChordTone flag per fretboard position, and ScaleDiagram.tsx
renders a three-tier hierarchy — root (biggest dot) > chord tone (a safe note to land a phrase
on) > plain scale tone (a passing tone) — with a small legend. No new dependencies, and we
verified live that all three dot tiers render correctly during playback.
VexTab/VexFlow: a real, maintained library — solving a different problem
VexFlow is the one library here that’s genuinely well-maintained, and we still didn’t use it. It renders staff notation and tab, which is a different data model entirely from the position diagrams GuitarTechHub actually needs. Pulling it in would have meant learning and wiring up a notation-rendering engine to solve a “where do I put my finger” problem that a hand-built SVG fretboard already solves. The lesson here wasn’t “avoid maintained libraries” — it was “check that the library’s actual data model matches the problem before reaching for it,” which is easy to skip when a library’s name sounds like an exact match.
Tonal.js: deliberately not adopted, even though it’s a solid library
Tonal.js is a legitimate, well-regarded music theory library, and we considered it as the
theory engine underneath scale-suggestion.ts. We didn’t adopt it, and the reason is specific
to how that file is written, not a knock on Tonal.js itself.
scale-suggestion.ts maps each supported chord quality to a scale via an exhaustive switch
statement with no default case — which means if a new ChordQuality is ever added to the type
without updating the scale mapping, the build fails to compile. That’s a deliberate safety net,
not an oversight. Swapping in an external theory library would mean giving up that compile-time
guarantee across a wide, already-tested surface of code, for a capability upgrade — a bigger
chord-quality vocabulary — that GuitarTechHub doesn’t currently need. If the site’s supported
chord qualities ever genuinely need to grow past the current set, Tonal.js is still the first
thing we’d reach for. Until then, adding it would be trading a real safety guarantee for
flexibility nothing is asking for yet.
The pattern across all four
None of these were rejected because they’re bad libraries. Two were unmaintained relative to how much we’d be depending on them; one solves an adjacent but different problem; one would have quietly removed a safety net that’s actively catching bugs today. Checking an open source library seriously — real maintenance status, real dependency weight, real fit against the existing code’s actual guarantees — usually takes less time than integrating it would have, and it’s the difference between a considered decision and just reaching for the first search result.