A self-hosted ListenBrainz and Last.fm frontend that stores metadata and cover images.
It includes storing scrobbles, metadata enrichment, and an interactive PureScript frontend for exploration of your listening habits.
You can see it for yourself - scrobbler.mtmn.name
- Architecture — Deep dive into the system components, data flow, and FFI usage.
- DuckDB — Schema details, analytical queries, and tools for data exploration.
This project uses just and Nix for development and deployment.
# Enter the development shell (includes PureScript, DuckDB, etc.)
just shell
# Build
just nix build
# Run the binary built by Nix
just nix run# Install dependencies
npm install
npx spago install
# Build the project
npm run build
# Run tests
npx spago test
# Build an optimized release
npm run release
# Run the application
npx spago run| Variable | Default | Description |
|---|---|---|
CORPUS_USERS_FILE |
users.json |
Path to the multi-user config file |
DATABASE_PATH |
(cwd) | Root directory for all user database files |
PORT |
8000 |
HTTP port to listen on |
LASTFM_API_KEY |
— | Last.fm API key (required when any user has lastfmUser set; also used for genre and cover art fallback) |
DISCOGS_TOKEN |
— | Discogs token for cover art and genre fallback |
S3_BUCKET |
— | S3 bucket name for cover art caching and backups |
S3_REGION |
us-east-1 |
S3 region |
AWS_ACCESS_KEY_ID |
— | S3 credentials |
AWS_SECRET_ACCESS_KEY |
— | S3 credentials |
AWS_ENDPOINT_URL |
— | S3-compatible endpoint (e.g. for MinIO) |
AWS_S3_ADDRESSING_STYLE |
— | Set to path for path-style S3 URLs |
COSINE_API_KEY |
— | cosine.club API key for similar tracks |
METRICS_ENABLED |
false |
Set to true to expose Prometheus metrics at /metrics |
| Field | Default | Description |
|---|---|---|
slug |
— | URL slug ("" for root user, "filip" for /u/filip) |
name |
— | Display name for the user (defaults to slug if not provided) |
listenbrainzUser |
— | ListenBrainz username to sync scrobbles from |
lastfmUser |
— | Last.fm username to sync scrobbles from |
databaseFile |
corpus.db |
Path to the user's DuckDB database file |
initialSync |
false |
Perform a full historical sync on first run |
coverCacheEnabled |
true |
Enable cover art caching to S3 |
backupEnabled |
false |
Enable database backups to S3 |
backupIntervalHours |
1 |
Backup frequency |