tonal_py¶
A pragmatic Python port of the tonal JavaScript music theory library — version 6.4.3, with 23 namespaces covering notes, intervals, chords, scales, keys, modes, voicings, rhythm patterns, and more.
from tonal_py import Note, Chord, Scale, Key
Note.midi("C4") # 60
Chord.get("Cmaj7").notes # ('C', 'E', 'G', 'B')
Scale.get("C major").notes # ('C', 'D', 'E', 'F', 'G', 'A', 'B')
Key.major_key("C").chords # ('Cmaj7', 'Dm7', 'Em7', 'Fmaj7', 'G7', 'Am7', 'Bm7b5')
Why tonal_py¶
- Behavior parity with tonal.js. The data tables (106 chord types, 92
scale types, 7 modes, 4 key scales) are transcribed verbatim and verified
row-by-row against the JS implementation. If
tonalreturns a value, so do we. - Pythonic at the surface, faithful underneath. Function names use
snake_case(Note.from_midi, notNote.fromMidi); types are frozen dataclasses; nothing depends on a JS runtime. - Zero runtime dependencies. Same ethos as upstream tonal.
Install¶
Requires Python 3.13+.
What's next¶
- Getting Started — a 5-minute tour of the most common operations (notes, chords, scales, transposition).
- Concepts — how tonal models pitch, why notes have coordinates, what a "pitch class set" is.
- API Reference — every function in every namespace, generated from the source.
- Naming Conventions — exact
tonal.js → tonal_pyidentifier mapping for porting JS code.
Status¶
All 7 phases of the port are complete. 514 tests pass, including per-row checks for every chord and scale type against the JS oracle.