← Projects

open source · OFL · npm @chordlang/*

ChordFont

Jazz chord symbols, engraved properly — as a font.

npm install @chordlang/font

ChordFont is an OpenType font that turns plain text like Emaj7#11 or Am7b5 into publisher-quality engraved chord symbols. No rendering library, no canvas, no SVG pipeline — the engraving logic lives inside the font itself, so anywhere you can set a typeface, you can typeset Real Book-style chords.

Cmaj7 Dm7b5 F♯m7 G13 B♭7 engraved by ChordFont

Most chord-rendering projects ship a JavaScript library or an image generator, which means every use case requires an integration. A font inverts that: every text field in the world becomes a renderer. Out of the box it works in notation software text blocks (Dorico, MuseScore, Finale), word processors, Figma mockups, DAW markers, slide decks, web pages via a single @font-face rule, and anything that exports to PDF — the engraving survives export because it is the text. There’s no SDK to adopt and no runtime to version; distribution is just installing a font, which is a workflow musicians and engravers already understand.

That’s the wedge. Because the whole pipeline — grammar, normalizer, glyph substitution rules — is ours, first-party tooling can sit on the same core: a web playground, a lead-sheet editor (.cfmd charts), harmonic graphs (.cfgv / Graphviz), a hosted rendering API, and a companion stafffont for staff notation. The font gets ChordFont into existing workflows for free; the tools are where the product surface grows. The monorepo ships as chordlang.

How the engraving works

The pipeline has a deliberate split between harmony and engraving.

Harmony lives in the normalizer. A PEG grammar parses chord syntax, and a normalizer (wrapping tonal) resolves it into a canonical factor set. This is where music-theory rules apply — for example, altered fifths use replace-not-append merging, so E7b5 correctly replaces the perfect fifth rather than stacking a ♭5 on top of it (verified across E7, E9, and E13 with both ♭5 and ♯5).

Engraving lives in the font’s GSUB tables. Once text is normalized, there’s no render-time tokenization — the font consumes the plain string and OpenType glyph substitution does the rest. Ligature and contextual substitutions map ASCII sequences to engraved forms: maj7 to the triangle, m7b5 to the half-diminished ø, superscripted tension stacks, and so on.

The subtle part is accidental binding: a flat after a root letter (Bb) is visually a different object than a flat inside an alteration (b9), and the font resolves this contextually — flat.root / sharp.root glyph forms are substituted only when the accidental follows a note letter A–G, with .alt forms used everywhere else. That distinction — which accidental “belongs” to what — is exactly what separates engraved output from text-with-music-symbols-pasted-in.

Each concern has its own spec: the GSUB shape tests are the engraving spec, the normalizer test suite is the harmony spec, and a stress-test harness renders the full chord vocabulary as a regression fixture, so glyph-metric changes can’t silently break shapes elsewhere.

Glyphs & licensing

Glyphs derive from Petaluma (Steinberg’s handwritten SMuFL font) and are licensed under the SIL Open Font License. The font itself stays OFL — free forever — which is precisely what makes the strategy work: nothing stops the font from spreading, and the commercial surface is the tooling built on top of it.

Roadmap

  • ChordFont OpenType build + GSUB shape tests
  • Chord normalizer (tonal wrapper) + PEG chart grammar
  • HTML renderer, playground, Graphviz harmonic graphs
  • npm @chordlang/* packages (parser, chord, render, font, graph, cli)
  • Hosted rendering API
  • Companion stafffont for staff notation