New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

tonnetz

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tonnetz

Neo-Riemannian music theory: PLR transformations, hexatonic and octatonic cycles, the Tonnetz lattice, and shortest transformation paths between triads. Typed, zero dependencies.

latest
Source
npmnpm
Version
0.3.0
Version published
Maintainers
1
Created
Source

tonnetz

tonnetz logo

CI License: MIT

Neo-Riemannian music theory for JavaScript and TypeScript: the P, L, R transformations, hexatonic and octatonic cycles, the Tonnetz lattice, and shortest transformation paths between triads. Typed, zero runtime dependencies, runs in the browser and in Node.

Install

npm install tonnetz

30-second example

import { triad, p, l, r, transform, hexatonicPole, pathBetween, triadName } from "tonnetz";

const c = triad(0, "major");        // C major

p(c);                                // { root: 0, quality: "minor" }   C minor
l(c);                                // { root: 4, quality: "minor" }   E minor
r(c);                                // { root: 9, quality: "minor" }   A minor

triadName(hexatonicPole(c));         // "G# minor"  (no common tones)
triadName(transform(c, "LPR"));      // "C# minor"  (apply L, then P, then R)

pathBetween(c, triad(5, "minor"));   // "PLR"  shortest route to F minor

Chord symbol parsing (v0.3.0)

import { parseChord, chordCandidates } from "tonnetz";

parseChord("C");       // { root: 0, quality: "major",    pitchClasses: [0, 4, 7] }
parseChord("Cm7");     // { root: 0, quality: "minor7",   pitchClasses: [0, 3, 7, 10] }
parseChord("F#maj7");  // { root: 6, quality: "major7",   pitchClasses: [1, 6, 10, 11] }
parseChord("Bbdim7");  // { root: 10, quality: "diminished7", pitchClasses: [0, 3, 6, 10] }
parseChord("Csus4");   // { root: 0, quality: "sus4",     pitchClasses: [0, 5, 7] }
parseChord("xyz");     // null

// Identify all chords that contain the pitch classes 0, 4, 7 (C major triad).
chordCandidates([0, 4, 7]);
// [{ root: 0, quality: "major", symbol: "C" }, ...]

Triads are { root, quality } with root a pitch class (0..11, C = 0). All functions are pure.

Why this exists

Neo-Riemannian theory (the PLR transformations and the Tonnetz) is standard in modern music theory, but there is no JavaScript or TypeScript library for it. tonal covers tonal harmony but not transformational theory; Tone.js is for audio; music21 is a large Python framework that does not run in a browser. tonnetz fills that gap with a small, correct, dependency-free engine, well suited to interactive teaching tools and analysis.

Comparison

Capabilitytonnetztonalmusic21
P, L, R transformationsyesnoyes
Compound transformationsyesnoyes
Hexatonic / octatonic cyclesyesnopartial
Shortest PLR pathyesnono
Tonnetz lattice coordinatesyesnono
Common chord symbol parsingyesyesyes
Zero runtime dependenciesyesyesno
Runs in the browseryesyesno
LanguageTSJS/TSPython

API

Triads

  • triad(root, quality) constructs a triad, reducing the root modulo 12.
  • triadToPitchClasses(t) returns the three pitch classes.
  • isConsonantTriad(pcs) identifies a pitch-class set as a major or minor triad, or null.
  • triadName(t) returns a readable name such as "C major".
  • allTriads() returns all 24 consonant triads.
  • triadsEqual(a, b) compares root and quality.

Transformations

  • p(t), l(t), r(t) are the Parallel, Leittonwechsel, and Relative transformations.
  • n(t) (Nebenverwandt) and s(t) (Slide) are the named compound transformations.
  • transform(t, "LPR") applies a sequence of operations, left to right.
  • hexatonicPole(t) returns the maximally distant triad (LPL).

Cycles and paths

  • hexatonicCycle(t) returns the six triads of the hexatonic cycle.
  • octatonicCycle(t) returns the eight triads of the octatonic cycle.
  • pathBetween(from, to) returns the shortest P, L, R sequence mapping one triad to another.

Geometry and relations

  • commonTones(a, b) counts shared pitch classes.
  • pitchAtLattice(fifths, majorThirds) maps a Tonnetz lattice coordinate to a pitch class.

Chord symbol parsing

  • parseChord(symbol) parses a standard chord symbol string (e.g. "Cm7", "F#maj7", "Bbdim7", "Csus4", "CmM7") into { root, quality, pitchClasses }. Root is a pitch class (C = 0, C# = 1, ..., B = 11). Accepts all 12 roots with sharps and flats. Returns null for unrecognized input.
  • chordCandidates(pcs) is the inverse: given a pitch-class array, returns all recognized chord symbols whose pitch-class content exactly matches, sorted deterministically by root then quality.
  • ChordQuality is the type for the quality field, a union of string literals.

Supported quality labels and the spellings accepted for each:

Quality labelAccepted suffixesExample
major(none), maj, MC, Cmaj
minorm, min, -Cm, Cmin
diminisheddim, oCdim, Co
augmentedaug, +Caug, C+
dominant77C7
major7maj7, M7Cmaj7
minor7m7, min7, -7Cm7
halfDiminished7m7b5, ø7, øCm7b5
diminished7dim7, o7Cdim7
sus2sus2Csus2
sus4sus4Csus4
minorMajor7mM7, m(maj7), min(maj7)CmM7

The transformations

  • P (Parallel) swaps quality on the same root: C major to C minor.
  • L (Leittonwechsel): C major to E minor, A minor to F major.
  • R (Relative): C major to A minor, A minor to C major.

Each preserves exactly two common tones, and each is its own inverse. Together they generate the dihedral group of order 24 acting on the 24 consonant triads, which is why a path always exists between any two triads. These properties are tested.

Roadmap

  • Seventh-chord transformations (Childs/Gollin neo-Riemannian operations on seventh chords).
  • Tonnetz triangle coordinates for rendering.

Examples

npm run example

Testing

npm test

Tests cover the exact textbook transformations and group-theoretic invariants (involutions, the two-common-tone property, and that every shortest path actually maps its source onto its target across all 24 triads).

Contributing

Issues and pull requests are welcome. See CONTRIBUTING.md.

License

MIT. See LICENSE.

Keywords

music

FAQs

Package last updated on 17 Jun 2026

Related posts