# music21: a Python toolkit for computer-aided musical analysis

> music21 is a BSD-licensed Python library for parsing, generating and analysing symbolic music. It is aimed at musicologists and researchers who can write Python, and it installs from PyPI on Python 3.12 or newer.

**cuthbertLab/music21** — music21: a Toolkit for Computer-Aided Musical Analysis and Computational Musicology

- Repository: https://github.com/cuthbertLab/music21
- Website: https://www.music21.org/music21docs/
- Stars: 2,588 · Forks: 457
- Language: Python
- License: BSD-3-Clause
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/cuthbertlab-music21

## What music21 is for, and who it is written for

music21 describes itself as a toolkit for computer-aided musical analysis and computational musicology. That phrasing is precise about the audience. It is not a notation program and not a DAW plugin. It is a Python library that turns a score into objects you can query, slice and compare in code.

The people who get value from it are musicologists, music theory researchers, and students who are comfortable in Python and have a corpus of scores they want to ask questions of. The repository classifies the project under Artistic Software, Sound/Audio, MIDI and Conversion, and the Development Status classifier is Production/Stable. The project has been developed since 2006, with copyright attributed to Michael Scott Asato Cuthbert, and early support from the Seaver Institute, the National Endowment for the Humanities and MIT.

The mismatch to watch for is a user who wants to click through notes on a staff. music21 will parse and manipulate the score, but the README points to the User's Guide and module reference for how to do anything, and there is no graphical interface described there.

## How music21 represents a score in memory

The mechanism that matters is that music21 does not treat a file as text. It parses notation into a stream hierarchy, where a score contains parts, parts contain measures, and measures contain notes, chords and other elements. Analysis then becomes ordinary Python: iterate over the elements, filter them, compare them.

The repository layout supports this reading. The package directory music21/ sits alongside documentation/ and a dist/ directory, and the dependency list in pyproject.toml is telling. It pulls in numpy, matplotlib, jsonpickle, joblib, more_itertools, chardet, requests and webcolors. numpy and matplotlib point at numerical work and plotting. jsonpickle points at serialising object graphs. The optional extras group adds python-Levenshtein, which is an edit-distance library, and scipy. Edit distance is what you reach for when you are comparing sequences, and in this domain the sequences are notes and intervals.

So the data flow is: read a file, get a stream object, traverse it, compute something, and either plot it or serialise it. Everything else in the library is a specialised version of one of those steps.

## Installing music21 and running a first analysis

The README sends readers to the User's Guide installation page at music21.org, and to a Colab notebook for trying it without a local install. For a local install, the package is published as music21 and requires Python 3.12 or newer, per pyproject.toml.

The README gives this version-to-Python mapping: music21 v4 for Python 2 or 3.4, v5 for 3.5, v6 for 3.6, v7 for 3.7, v8 for 3.8 and 3.9, v9 for 3.10, and v10 for 3.11. Since v9 the project has supported at least the last two released Python versions, but rarely more, with an exception made for whatever version Google Colab runs.

The pyproject.toml declares the build backend and the runtime dependencies. This is the block that tells you what a plain install pulls in, and it is the only dependency list the repository gives you outside requirements.txt, which repeats the same eight names.

```toml
[build-system]
requires = [
    "hatchling>=1.8.1",
]
build-backend = "hatchling.build"
```

```toml
dependencies = [
    "chardet",
    "joblib",
    "jsonpickle",
    "matplotlib",
    "more_itertools",
    "numpy>=1.26.4",
    "requests",
    "webcolors>=1.5",
]
```

If you are developing against the repository rather than the release, pyproject.toml defines a dev dependency group that self-references music21[extras], and the comment there says that uv sync alone is enough to develop and test music21. The repository also ships a uv.lock file, which is what pins that workflow.

```toml
[dependency-groups]
# `dev` pulls in every extra via the `music21[extras]` self-reference
# so `uv sync` alone is enough to develop and test music21.
dev = [
    'music21[extras]',
    'coverage',
```

The README does not print a worked analysis example, so the honest statement is that the entry points are the corpus and converter modules documented in the module reference. The README does give the Colab URL https://tinyurl.com/m21colab and says to run all to set up an environment for the latest release. That is the fastest way to see the library behave before you commit to a local environment.

## The corpus is convenient and it is also a licence boundary

The bundled corpus is the feature that makes music21 pleasant to start with. You can parse a score by name without finding a file. It is also the part of the package with the most tangled rights situation, and the README addresses this directly rather than hiding it.

The BSD-3-Clause licence covers code files new to music21 and the documentation. It does not automatically cover everything shipped. The README states that externally provided software, including the MIT-licensed Lilypond/MusicXML test suite, may have other licences, and that the encoded musical scores in the corpus have their own copyrights and licences. The underlying music is believed to be public domain in the US, the EU, Canada and most of the world, and the encodings are either public domain or used by permission.

For anyone who needs a clean BSD licence across the whole system, the README says a no-corpus version of music21 is available on GitHub and from the FreeBSD repo. That is the practical escape hatch, and it is worth knowing it exists before you build a pipeline that assumes the corpus is always present.

The README also notes that the detailed licence explanation was moved out of LICENSE and music21/license.txt into the README in 2026, at v10, to make the licence more parsable by tooling, and that the move did not change anyone's rights. If your build scans LICENSE for licence text, that change is worth checking against your tooling.

## Where music21 stops being the right tool

The clearest limitation is the Python version policy. Since v9 the project supports at least the last two released Python versions, but rarely more. If your environment is pinned to an older interpreter for reasons outside your control, you are pushed onto an older music21 release, and the README's mapping table is the only guide offered. That is a real constraint for research groups with long-lived environments.

The second limitation is the documentation shape. The README does not explain the API. It links to a User's Guide and a module reference. If you are evaluating music21 from the README alone, you will not learn how to transpose a stream or find a cadence. Budget time for the User's Guide.

The third is scope. music21 works on symbolic notation. If your question is about audio, about performance timing, or about anything that requires listening to a recording rather than reading a score, the toolkit is aimed at a different layer. Nothing in the dependency list suggests an audio analysis stack.

Finally, the contributing guide requires AI declarations, and the README asks contributors to review it periodically because it changes. If you plan to submit patches, read CONTRIBUTING.md before writing code, not after.

## Alternatives and what actually differs

The search data shows people looking for a music21 alternative, and the honest answer depends on which half of music21 you were using.

If you were using it to convert between formats, a dedicated converter is a smaller dependency. music21 brings numpy, matplotlib, joblib, jsonpickle and requests along with it. A format converter does not need a plotting library.

If you were using it for statistical work on symbolic corpora, the difference is in the object model. music21 gives you a stream hierarchy with named measures and parts, and analysis is traversal plus filtering. A dataframe-first approach flattens the score into rows of note events and loses the structural nesting unless you encode it yourself. That is faster for counting and worse for anything that asks about a measure as a unit.

If you were using it for notation rendering, that is outside music21's stated purpose. The README describes analysis and computational musicology, and the licence discussion mentions Lilypond only as an externally provided test suite, not as a rendering backend you are being sold.

The real dividing line is whether your questions are about musical structure or about note-event statistics. music21 is built for the first.

## Maintenance, releases and upgrade cost

The repository is not archived, and the last push was on 2026-09-23. Recent releases are v10.5.0 on 2026-06-17, v10.3.0 on 2026-05-26, and v10.1.0 on 2026-05-16. That is a steady release cadence within the v10 line.

The upgrade cost is set by the Python support policy rather than by API churn alone. Because the project supports roughly the last two Python releases, a Python upgrade in your environment can force a music21 upgrade at the same time. The README's version table exists precisely because that coupling has bitten people before.

On licence: the package is BSD-3-Clause, which the README summarises as free to use as long as you keep the LICENSE file and copyright statements. The complications are the ones already described, the MIT-licensed test suite and the per-score rights in the corpus. If you redistribute music21 with the corpus, you are redistributing material with rights that the BSD licence does not grant you. The no-corpus build exists for that reason. This is a description of what the README says, not legal advice; if redistribution matters to your organisation, have someone read LICENSE and the corpus notes.

## Conclusion

Adopt music21 if you already write Python and your data is symbolic: scores, MIDI files, MusicXML exports, or the bundled corpus. Do not adopt it if you need a graphical score editor or a real-time audio pipeline; the repository describes a library, not an application. Before committing, check three things: that your Python is 3.12 or newer, because pyproject.toml sets requires-python to >=3.12; that your project can carry the BSD-3-Clause notice plus the separate copyrights on the encoded corpus scores; and that the modules you need are covered by the module reference, since the README points to the User's Guide and module documentation rather than describing the API itself.

## FAQ

### Is music21 free to use?

Yes. The README states that music21 is open-source software released under the BSD 3-clause licence, and summarises it as free to use as long as you keep the LICENSE file and copyright statements. The encoded scores in the bundled corpus carry their own copyrights and licences, which the BSD licence does not cover.

### What is music21 in Python?

It is a Python library described as a toolkit for computer-aided musical analysis and computational musicology. It parses symbolic music into a stream hierarchy of parts, measures and notes so that analysis can be done in ordinary Python code.

### How do I install music21?

The README points to the User's Guide installation page at music21.org and to a Colab notebook for trying it without installing. For a local install the package is named music21 and pyproject.toml requires Python 3.12 or newer.

### How do I use music21?

The README does not walk through usage; it links to the User's Guide and the module reference for that. The starting point in code is the corpus and converter modules, which load a score into a stream object you can traverse.

### What is a music21 alternative?

It depends on which part of music21 you were using. For format conversion a dedicated converter is a smaller dependency than a package that also pulls in numpy and matplotlib; for note-event statistics a dataframe approach is faster but loses the measure and part hierarchy that music21's stream model preserves.

## Sources

- [cuthbertLab/music21 on GitHub](https://github.com/cuthbertLab/music21)
- [License: BSD-3-Clause](https://github.com/cuthbertLab/music21/blob/master/LICENSE)
- [Project website](https://www.music21.org/music21docs/)
- [README](https://github.com/cuthbertLab/music21/blob/master/README.md)
- [Releases](https://github.com/cuthbertLab/music21/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/cuthbertlab-music21
