# listenbrainz-server turns a listening history into open data

> The ListenBrainz server is the MetaBrainz Foundation's service for recording what you listen to and drawing insights from it, and the repository contains everything needed to run it: a Flask API, a React front end, a set of Spark jobs and the data pipeline. It is published as open data and the code is GPL-2.0, which makes it unusual among music services.

**metabrainz/listenbrainz-server** — Server for the ListenBrainz project, including the front-end (javascript/react) code that it serves and all of the data processing components that LB uses.

- Repository: https://github.com/metabrainz/listenbrainz-server
- Website: https://listenbrainz.org/
- Stars: 1,041 · Forks: 379
- Language: Python
- License: GPL-2.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/metabrainz-listenbrainz-server

## A listening history service that publishes its data

ListenBrainz keeps track of the music you listen to and gives you insights into your listening habits. The project describes itself as completely open source and says it publishes its data as open data.

That last part is the design decision that makes the project unusual. Most listening history services keep the data to themselves, because the data is the product. Here the service exists to collect the data and to make it available, and the API is offered so that you can do more with it than the built-in visualisations allow.

The operator is the MetaBrainz Foundation, which the README describes as having a long-standing history of curating, protecting and making music data available to the public. That is a different institutional shape from a startup, and it explains two things a reader might otherwise find odd. The first is the open data commitment, and the second is the commercial use arrangement, which is that all of the data is available for commercial use, with commercial use support tiers described on the MetaBrainz site. So the data is free to use commercially, and the way an organisation gets support is a tier, not a licence.

The audience for the repository is two-sided. There are users of the hosted service at listenbrainz.org, and there are developers who want to run their own instance or build on the data.

The licence is GPL-2.0, with the notice in the README stating copyright 2017 MetaBrainz Foundation Inc. and the standard GNU General Public License version 2 or later terms.

## One repository, four kinds of code

The project description covers the scope in a single sentence. The repository contains the server for the ListenBrainz project, including the front-end JavaScript and React code that it serves and all of the data processing components that ListenBrainz uses.

The repository layout shows how that splits in practice. The `listenbrainz/` directory is the service itself, with `manage.py` as the entry point. The `frontend/` directory holds the web client, and the `listenbrainz_spark/` directory holds the Spark jobs, with `spark_manage.py` as its entry point and `spark_config.sh.sample` as a configuration template. The `data/` directory holds the static data, `admin/` the administration, `mbid_mapping/` the mapping between MusicBrainz identifiers, `docker/` the container setup, and `docs/` the documentation. There is also `mlhd_manage.py` for a separate management entry point and `run_websockets.py` for the websocket side.

The tests are split the same way, with a `pytest.ini` and a separate `pytest.spark.ini` for the Spark tests, and the shell scripts `develop.sh` and `test.sh` as the developer entry points. There is a `consul_config.py.ctmpl` template for Consul configuration, which tells you the service was expected to run behind a configuration service.

The `data/` directory is worth a second look, because it is the physical embodiment of the open data promise. The listening data is a published artefact that ships with the code, not a by-product that you have to scrape out of the running service.

For the front end, the JavaScript side is built with webpack and Babel, styled with Sass, and tested with Jest. The `package.json` scripts show the whole development cycle, and the test script pins the timezone, since a test that depends on the machine's locale is a test that fails on someone else's laptop.

```json
"test": "TZ='Europe/London' jest",
"type-check": "tsc --noEmit"
```

The CI variant adds a JUnit reporter and a JUnit output directory, and the type check is a separate script rather than part of the test run, which is the usual arrangement when the type check is slow.

## The dependency list is the architecture

The `requirements.txt` is long and entirely pinned, and reading it tells you more about the service than the prose does.

The web tier is Flask, with Flask-Login for the session handling, Flask-Admin for the administration interface, Flask-WTF and WTForms for forms, and Flask-SQLAlchemy on top of SQLAlchemy 2.0.46 for the data access, with psycopg2-binary for PostgreSQL. Redis is there for the queueing and caching layer, and kombu, the messaging library, sits on top of it. uWSGI and gevent with gevent-websocket serve the application, and Flask-SocketIO provides the socket layer that `run_websockets.py` drives.

The data side is where the project's distinguishing feature sits. numpy, pandas and pyarrow are the analytical stack, and `listenbrainz_spark/` is where the heavy processing happens. The topics attached to the repository include `big-data` and `spark`, and there is a separate Dockerfile for Spark, a `requirements_spark.txt`, a separate pytest configuration, and a `spark_manage.py` entry point, so the Spark jobs are a first class part of the system rather than an afterthought.

The external integrations are visible too. `mbdata` and `brainzutils` are MetaBrainz's own libraries taken from git, `datasethoster` is another of their git dependencies, spotipy is the Spotify client, typesense is the search index, sentry-sdk is the error reporting, pyjwt with crypto is the token handling, and boto3 and feedgen point at object storage and feed generation.

Two things stand out for an adopter. The data pipeline is genuinely large, since this is a service that ingests events from many clients and computes derived data such as listens per artist over time. And the search and recommendation pieces are real, with typesense and the `troi` library for recommendations alongside it, rather than being bolted on later.

## Building the documentation and the client locally

The development environment documentation is the reference for setting up a working copy, and the README is explicit that the instructions are for development and that installation in a production environment may be different.

The one command sequence given in the README is for the documentation, which is Sphinx based and lives in the `docs` directory.

```bash
cd listenbrainz-server/docs
pip install -r requirements.txt
make clean html
```

For working with Spark, there is a second environment to set up, and the README points at a separate Spark development environment document rather than trying to fold it into the main one. That split is a hint about how the team works, since the two environments have genuinely different requirements and a developer doing only API work should not have to install a Spark toolchain.

The front end has its own build. The `package.json` scripts show a development build with webpack in watch mode, a production build, a separate Sass compilation step, and a type declaration build with `tsc --emitDeclarationOnly`. The lint and format scripts cover JavaScript, TypeScript and Sass, with the CI variants using `--max-warnings 0` so that a warning fails the build.

There is a Dockerfile for the service, built on a MetaBrainz Python base image at 3.13, with a Node 20 Alpine stage for the front end, plus a separate `Dockerfile.nginx.prod` for the production reverse proxy and `Dockerfile.spark` for the Spark jobs. The base image also installs the PostgreSQL client, redis-tools, rsync and zstd, and it pulls in `dockerize` for waiting on services and `sentry-cli` for source map uploads in production.

That last detail is a good indicator of what this codebase is. The presence of a Sentry release step in the Docker build, with a schema version of 1.0.0-rc1, is the signature of a service that runs in production and is operated by a small team.

## Running your own instance is a different project from using the data

The documentation draws a line that matters for anyone evaluating this repository.

Using ListenBrainz means using the hosted service at listenbrainz.org, or at minimum using its API and its published data. The API documentation is on Read the Docs, the data is open and available for commercial use, and the announcement blog is where changes to the service are announced. The README asks that anyone using the services in a production system follow the blog, which is a small sentence with a large implication, since it means the service's behaviour can change underneath you and the API is not a frozen contract.

Running your own instance is a different undertaking. The service is a Flask application with PostgreSQL, Redis, a search index, a websocket layer, a Spark pipeline and a React client, and the documentation says the development environment instructions are for development and that production installation may be different. Self-hosting therefore means reading a set of deployment notes that are not in this README and operating a stack with several stateful components.

The client side also matters. The data is submitted by clients, and the repository is the server, not the players or the browser extensions, so the scope of what you can usefully self-host is narrower than it might first appear.

The contribution model is worth noting too. The README asks people to donate to the MetaBrainz Foundation, to use the issue tracker at tickets.metabrainz.org, and to join IRC, Matrix or Discord on the #metabrainz channel. For a foundation-run project that is a normal arrangement, and it means the issue tracker and the chat channel are where the real questions get answered rather than the repository itself.

## Conclusion

listenbrainz-server suits a developer who wants to build on listening history as a dataset, or an organisation that wants to run its own instance rather than shipping listening data to a third party. It is the wrong tool for a small deployment, because the service assumes PostgreSQL, Redis, a Spark cluster and a search index, and the documentation says production installation may be different from the development environment. Check first what the API and the open data dump give you, because for most uses of listening data that is the part you want, and read the development environment documentation before attempting a self-hosted instance.

## FAQ

### What is the listenbrainz-server repository?

It is the server for the ListenBrainz project, and it contains the Flask API, the JavaScript and React front-end code the server serves, and the data processing components ListenBrainz uses, including a set of Spark jobs under `listenbrainz_spark/`.

### Can the ListenBrainz data be used commercially?

Yes. The README states that all of the data is available for commercial use, and that information about the commercial use support tiers is on the MetaBrainz site. The code itself is licensed under the GNU General Public License version 2 or later.

### How do I build the ListenBrainz documentation locally?

The README gives the sequence as `cd listenbrainz-server/docs`, then `pip install -r requirements.txt`, then `make clean html`. Working on the Spark jobs needs a separate Spark development environment, which has its own documentation page.

### What does the ListenBrainz stack run on?

The pinned requirements include Flask with Flask-Login, Flask-Admin, Flask-SQLAlchemy and SQLAlchemy, PostgreSQL through psycopg2-binary, Redis with kombu, uWSGI and gevent for serving, numpy, pandas and pyarrow for the analytical side, typesense for search, and Sentry for error reporting. The container images are built on a Python 3.13 base with a Node 20 Alpine stage, plus separate images for nginx in production and for Spark.

## Sources

- [License: GPL-2.0](https://github.com/metabrainz/listenbrainz-server/blob/master/LICENSE)
- [metabrainz/listenbrainz-server on GitHub](https://github.com/metabrainz/listenbrainz-server)
- [Project website](https://listenbrainz.org/)
- [README](https://github.com/metabrainz/listenbrainz-server/blob/master/README.md)
- [Releases](https://github.com/metabrainz/listenbrainz-server/releases)

---

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