Gomaink/your_lastfm
Gomaink/your_lastfm has 149 GitHub stars and 10 forks. GitHot measured 0 stars in 24 hours, 0 in 7 days, and +1 in 15 days. Last checked 2026-11-10 01:11 UTC. Last push 2026-08-03.
Turn your Last.fm scrobbles into a complete, private dashboard.
What you can do
- Incremental Last.fm synchronization with a configurable overlap window.
- Automatic first full sync when the database is empty.
- Cross-process sync lock, resumable sync windows, progress reporting, retries, and a daily integrity check.
- Dashboard with top artists, albums, tracks, daily activity, previous-period trends, a local-time Listening Clock, account statistics, and recent scrobbles.
Measured star growth
- in 24h
- 0
- in 7 days
- 0
- in 15 days
- +1
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
README.md
OriginalYourLastFM
YourLastFM is a self-hosted Node.js dashboard that synchronizes your Last.fm scrobbles into SQLite, displays listening statistics, compares your taste with friends, builds custom group leaderboards, and generates shareable recap images.
Features
- Incremental Last.fm synchronization with a configurable overlap window.
- Automatic first full sync when the database is empty.
- Cross-process sync lock, resumable sync windows, progress reporting, retries, and a daily integrity check.
- Dashboard with top artists, albums, tracks, daily activity, previous-period trends, a local-time Listening Clock, account statistics, and recent scrobbles.
- Direct Last.fm links for artists, albums, and tracks.
- Persistent SQLite dashboard cache invalidated after syncs, imports, and manual cover changes.
- Last.fm friends comparison with common artists, albums, and tracks, including resilient artwork and avatar fallbacks.
- Custom local leaderboard groups with public Last.fm users, exact date ranges, member standings, combined artist/album/track charts, and top-track drill-downs.
- Standard and Instagram Story recap images generated on the server.
- Automatic album/artist image lookup, persistent image cache, and manual album-cover uploads.
- CSV import and streaming CSV export.
- Persistent SQLite database and uploaded covers through the
datavolume.
Requirements
- Docker and Docker Compose, or Node.js 22 with the native dependencies required by
canvasandbetter-sqlite3. - A Last.fm API key.
Create an API account at the Last.fm API website and copy .env.example to .env:
cp .env.example .env
At minimum, configure:
LASTFM_API_KEY=your_lastfm_api_key
LASTFM_USERNAME=your_lastfm_username
Run with Docker Compose
Use the published image:
docker compose pull
docker compose up -d
Or build the current source locally:
docker compose up -d --build
Open:
http://localhost:1533
The API starts immediately. Synchronization runs in a separate managed process, so a large initial history import does not keep the web interface offline. If a Last.fm page keeps failing after all retries, the original from/to window is persisted and retried on the next run instead of advancing past the missing page.
Useful commands:
# Follow both API and synchronization logs
docker compose logs -f
# Rebuild after updating the source
docker compose up -d --build
# Stop the application without deleting ./data
docker compose down
The Docker image rebuilds canvas from source during every platform build. This avoids ARM64 prebuilt-library incompatibilities on Raspberry Pi 5 and other systems using 16 KB or 64 KB memory pages.
Do not delete the local data directory unless you intentionally want to remove the SQLite database, uploaded covers, and downloaded share-image cache.
Run without Docker
npm ci
npm start
Run the scheduler in another terminal:
npm run start:cron
Manual synchronization commands:
npm run sync
npm run sync:full
npm run sync:initial
Configuration
The defaults are documented in .env.example.
| Variable | Purpose | Default |
|---|---|---|
PORT |
HTTP port | 1533 |
SYNC_CRON |
Incremental sync schedule | */5 * * * * |
INTEGRITY_CRON |
Last.fm/local count check | 0 3 * * * |
INTEGRITY_MISSING_THRESHOLD |
Missing scrobbles required before the integrity check starts a full repair sync | 1 |
SYNC_OVERLAP_SECONDS |
Re-fetch window used to safely catch late scrobbles | 86400 |
LASTFM_REQUEST_DELAY_MS |
Delay between Last.fm history pages | 250 |
LASTFM_REQUEST_TIMEOUT_MS |
Last.fm request timeout | 15000 |
DASHBOARD_CACHE_TTL_MS |
Persistent dashboard cache lifetime in milliseconds; 0 disables time-based expiry |
300000 |
STATIC_ASSET_CACHE_SECONDS |
Browser cache lifetime for local JavaScript, CSS, and images | 300 |
LEADERBOARD_CACHE_TTL_MS |
Persistent lifetime for generated leaderboard results; 0 disables time-based expiry |
900000 |
LEADERBOARD_PROFILE_TTL_MS |
Lifetime of cached Last.fm user profiles | 86400000 |
LEADERBOARD_ALBUM_TTL_MS |
Lifetime of cached album track lists | 2592000000 |
LEADERBOARD_REQUEST_CONCURRENCY |
Concurrent Last.fm requests while building group charts | 4 |
LEADERBOARD_MAX_GROUPS |
Maximum local leaderboard groups | 50 |
LEADERBOARD_MAX_MEMBERS |
Maximum Last.fm users in one group | 20 |
LEADERBOARD_MAX_RANGE_DAYS |
Maximum inclusive leaderboard date range | 366 |
EXTERNAL_REQUEST_CONCURRENCY |
Concurrent metadata/image lookups | 4 |
FRIENDS_CACHE_TTL_MS |
In-memory cache lifetime for the Last.fm friends list | 300000 |
IMAGE_FAILURE_CACHE_MS |
Time before retrying an image lookup that returned nothing | 600000 |
METADATA_FAILURE_CACHE_MS |
Time before retrying missing track metadata | 600000 |
SHARE_IMAGE_CONCURRENCY |
Concurrent recap image loads | 4 |
SHARE_MAX_CONCURRENT |
Maximum simultaneous recap renders | 2 |
SHARE_IMAGE_MAX_BYTES |
Maximum downloaded image size | 10485760 |
CORS_ORIGIN |
Optional comma-separated external origins | empty |
Dashboard caching
The browser loads the main Dashboard through a single /api/dashboard request. The generated response is stored in SQLite, so reopening the Dashboard or returning to a previously used filter does not repeat the expensive aggregation and artwork lookups.
The cache is invalidated automatically when:
- a synchronization completes;
- a CSV import adds scrobbles;
- a manual album cover is changed.
Rolling periods compare against the immediately preceding equivalent window. The Listening Clock uses the timezone offset reported by the browser.
Custom leaderboards
Open Leaderboards from the sidebar, create a group, and add at least two public Last.fm usernames. The username configured in LASTFM_USERNAME can be added with the Add me button.
Each group supports:
- 7, 30, 90, and 365-day presets;
- an inclusive custom date range;
- artist, album, and track rankings;
- member standings and per-item contribution counts;
- artist and album drill-downs for the group's most-played tracks;
- direct links to the corresponding Last.fm pages.
Groups and their caches are stored locally in stats.db; no separate account system or external YourLastFM service is involved. Last.fm requests are concurrency-limited, retried, and cached. If one member temporarily fails, the remaining data is still displayed as a partial result. Use Refresh to bypass the current chart cache.
Data and backups
Persistent files are stored under ./data:
data/
├── stats.db # scrobbles, settings, groups, and API caches
├── covers/
└── image-cache/
A basic backup can be made while the application is stopped:
docker compose down
cp -a data data-backup
SQLite uses WAL mode. When making a live filesystem-level backup, include stats.db, stats.db-wal, and stats.db-shm, or use SQLite's backup tooling.
Validation
npm run check
npm test
npm audit
License
MIT. See LICENSE.
Explore related projects
awesome-selfhosted/awesome-selfhosted
A list of Free Software network services and web applications which can be hosted on your own servers
335,563 starsimmich-app/immich
High performance self-hosted photo and video management solution.
118,645 starsStirling-Tools/Stirling-PDF
#1 PDF Application on GitHub that lets you edit PDFs on any device anywhere
96,149 starslouislam/uptime-kuma
A fancy self-hosted monitoring tool
93,425 stars