npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pcset

v0.4.0

Published

Post-tonal pitch-class set theory: normal order, prime form, interval-class vector, Z-relations, and set-class analysis. Typed, zero dependencies, browser and Node.

Readme

pcset

npm CI License: MIT

Post-tonal pitch-class set theory for JavaScript and TypeScript: normal order, prime form, interval-class vector, Forte numbers, Z-relations, complement, symmetry, and the full set-class catalog. Typed, zero runtime dependencies, runs in the browser and in Node.

Install

npm install pcset

30-second example

import { setClass, primeForm, forte, commonName, intervalVector, sameSetClass } from "pcset";

primeForm([0, 4, 7]);            // [0, 3, 7]  major triad
primeForm([0, 3, 7]);            // [0, 3, 7]  minor triad, same set class
intervalVector([0, 4, 7]);       // [0, 0, 1, 1, 1, 0]
forte([0, 4, 7]);                // "3-11"
commonName([0, 4, 7]);          // "major/minor triad (3-11)"
commonName([2, 6, 9]);          // "major/minor triad (3-11)"  -- any transposition
commonName([0, 2, 4, 6, 8, 10]); // "whole-tone scale (6-35)"
commonName([0, 2, 4, 5, 7, 9, 11]); // "diatonic / major scale (7-35)"
commonName([0, 1, 2, 3, 4]);    // null  -- no standard name
sameSetClass([0, 4, 7], [0, 3, 7]); // true

setClass([0, 1, 4, 6]);
// {
//   pcs: [0, 1, 4, 6],
//   normalOrder: [0, 1, 4, 6],
//   primeForm: [0, 1, 4, 6],
//   forte: "4-z15",
//   cardinality: 4,
//   intervalVector: [1, 1, 1, 1, 1, 1],   // all-interval tetrachord
//   complementPrimeForm: [0, 1, 2, 3, 5, 6, 7, 8],
//   zPartner: [0, 1, 3, 7],               // the other all-interval tetrachord
//   transpositionalSymmetry: 1,
//   inversionalSymmetry: 0,
// }

Pitch classes are integers, C = 0. Inputs may be unsorted, duplicated, or outside 0..11; they are reduced modulo 12.

Why this exists

Post-tonal analysis (prime form, interval-class vectors, Z-relations) is standard material in music theory, but the JavaScript ecosystem has no focused library for it. @tonaljs/pcset, the set module of the dominant JS music library, computes only set membership, subset, and superset; it does not compute normal order, prime form, interval vectors, inversion, complement, or Z-relations. music21 is excellent but is a large Python framework, not usable in a browser. The Python pcsets package was last released in 2007.

pcset fills that gap with a small, correct, dependency-free engine that is easy to embed in interactive theory and pedagogy tools.

Comparison

| Capability | pcset | @tonaljs/pcset | music21 | |---------------------------------|:-----:|:--------------:|:-------:| | Normal order | yes | no | yes | | Prime form | yes | no | yes | | Interval-class vector | yes | no | yes | | Transposition and inversion | yes | partial | yes | | Complement | yes | no | yes | | Z-relation detection | yes | no | yes | | Symmetry degrees | yes | no | yes | | Full set-class catalog | yes | no | yes | | Forte set-class numbers | 3 to 9 | no | yes | | Common set-class names | yes | no | yes | | Zero runtime dependencies | yes | yes | no | | Runs in the browser | yes | yes | no | | Language | TS | JS/TS | Python |

The chroma string and set number use the same encoding as tonal, so the two libraries interoperate.

API

All functions are pure. Inputs are read-only number arrays; outputs are normalized pitch-class sets (sorted, unique, 0..11).

Core

  • normalize(pcs) reduces raw integers to a normalized set.
  • normalOrder(pcs) returns the most compact cyclic ordering.
  • primeForm(pcs) returns the canonical set-class representative (Rahn algorithm), starting on 0.
  • intervalVector(pcs) returns the interval-class vector [ic1..ic6].
  • forte(pcs) returns the Forte set-class number (for example "3-11" or "4-z15"), or null.
  • commonName(pcs) returns a widely recognized common name for the set class (for example "whole-tone scale (6-35)"), or null when none is assigned. Transposition- and inversion-invariant.
  • setClass(pcs) returns the full SetClassInfo (normal order, prime form, interval vector, complement, Z-partner, symmetry).

Transform

  • transpose(pcs, n) transposes by n semitones (Tn).
  • invert(pcs) inverts about pitch class 0 (T0I).
  • invertAround(pcs, axis) inverts about an axis (TnI).
  • complement(pcs) returns the pitch classes not in the set.

Relations

  • equals(a, b), isSubsetOf(a, b), isSupersetOf(a, b)
  • isTranspositionOf(a, b), isInversionOf(a, b), sameSetClass(a, b)
  • isZRelatedTo(a, b)

Symmetry

  • transpositionalSymmetry(pcs), inversionalSymmetry(pcs)

Encoding and catalog

  • toChroma(pcs), fromChroma(chroma), toNumber(pcs), fromNumber(num)
  • catalog() returns the complete set-class catalog (224 classes) as a Map keyed by prime form.
  • catalogEntry(pcs) looks up the catalog entry for a set.

A note on prime form

Prime form here follows the Rahn algorithm (the convention used by Straus): take the more left-packed of the set's normal order and its inversion's normal order, each transposed to 0. For the small number of set classes where Forte and Rahn disagree (for example 5-20, 6-31, 7-20), this returns the Rahn form.

A note on Forte numbers

Forte numbers are provided for all set classes of cardinalities 3 to 9, including the 50 hexachords (cardinality 6), with the z designation marking Z-related classes (for example "6-z44"). Because a set class and its complement share a Forte ordinal, the labels for cardinalities 7 to 9 are derived from those for 3 to 5. The hexachord labels are cross-checked against the library's own catalog: the tests confirm that the z marking matches the catalog's interval-vector Z-relation detection for every hexachord, that all 50 classes are covered, and that each label is unique.

Roadmap

  • Abstract subset and superset relations between set classes.
  • Generalization to mod-n universes for microtonal work.

Examples

npm run example

Testing

npm test

The suite covers known prime forms and interval vectors, structural checks against the full set-class catalog (counts per cardinality, complement and Z-relation consistency), and property-based invariants (transposition and inversion preserve set class and interval vector, prime form is idempotent, encodings round-trip).

Contributing

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

License

MIT. See LICENSE.