A self-hosted music metadata editor with a modern, intuitive web UI.
Live Demo — login with demo / demo
Hosted on Fly.io with auto-stop to save costs. First load may take ~30s while the machine wakes up.
Demo is read-only: you can browse, filter, scan, view song edit history, and play songs, but metadata editing is disabled.
Tagr lets you browse, edit, and manage audio file tags from any browser — desktop or mobile. Just point it at your music folders, and get a clean three-panel interface for organizing your library — no desktop apps, no CLI wizardry.
- Edit 40+ metadata fields inline — title, artist, album, year, genre, composer, BPM, lyrics, and more
- Custom metadata — add, edit, and remove your own custom tags beyond the standard fields
- Album art management — view, replace, and upload cover images directly
- Star ratings (1–5) with a visual widget
- Support for track/disc numbering, sort fields, catalog numbers, barcodes, and extended tags
- Read-only display of audio properties (codec, bitrate, sample rate, channels, bits per sample)
- Full audit trail of every metadata change with old and new values
- Revert individual changes or bulk-select and undo multiple edits at once
- Searchable history with shift+click and ctrl+click multi-selection
- Per-song and per-folder history views
- Built-in audio player with interactive waveform visualization (WaveSurfer.js)
- Play/pause, previous/next track navigation
- Click-to-seek on the waveform
- Auto-advance to next song
- Collapsible sidebar player with album art, title, and artist display
- Three-panel layout — folder tree, song list, and detail editor side by side
- Folder tree with hierarchical navigation and real-time search
- Sorting on any column — title, artist, album, year, duration, bitrate, date added, and dozens more
- Advanced filtering — text, numeric ranges, date ranges, and boolean filters across all fields
- Customizable columns — show/hide any of 40+ columns to match your workflow
- Virtual scrolling and infinite pagination for large libraries
| Format | Supported |
|---|---|
| MP3 | Yes |
| FLAC | Yes |
| WAV | Yes |
| AAC | Yes |
| OGG | Yes |
| M4A | Yes |
| WMA | Yes |
| AIFF | Yes |
| Opus | Yes |
Lossless formats are automatically detected and displayed with a badge.
Tagr is fully responsive and works on phones and tablets. The mobile UI adapts to smaller screens with:
- Full-screen panels with swipe gestures to navigate between folders, song list, and detail editor
- Expanded music player with album art, waveform, and playback controls
- Touch-friendly editing — all edit actions are always visible (no hover required)
- Single-user authentication — password-protected access
- Resizable panels — drag to resize the three-panel layout to your liking
- Dark theme by default
- Toast notifications for operation feedback
- URL-based state — bookmarkable views with folder, song, sort, and filter state preserved in the URL
wget https://raw.githubusercontent.com/suitux/Tagr/main/docker-compose.ymlopenssl rand -hex 32Copy the output — you'll use it as AUTH_SECRET in the next step.
services:
tagr:
image: ghcr.io/suitux/tagr:latest
container_name: tagr
restart: unless-stopped
ports:
- "3000:3000"
environment:
- PUID=1000
- PGID=1000
- NODE_ENV=production
- DATABASE_URL=file:/data/tagr.db
- AUTH_SECRET=paste-your-generated-secret-here
- AUTH_USER=admin
- AUTH_PASSWORD=your-password-here
- AUTH_URL=https://your-domain.com
volumes:
- sqlite_data:/data
# Mount your music folder into the container:
- /path/to/your/music:/music
volumes:
sqlite_data:Multiple folders: If your music is spread across different host paths, mount them as subdirectories under
/music. Tagr scans/musicrecursively, so all subdirectories are included automatically:volumes: - /home/user/Music:/music/library - /mnt/nas/Music:/music/nasSet
MUSIC_FOLDERSonly if you want to restrict scanning to specific subdirectories (e.g., scan/music/librarybut skip/music/podcasts).
docker compose up -dNavigate to http://localhost:3000, log in with your credentials, and hit the scan button to index your library.
Requirements: Node.js 22+.
git clone https://github.com/suitux/Tagr.git
cd tagr
pnpm installCreate a .env file in the project root:
DATABASE_URL=file:./data/tagr.db
AUTH_SECRET="c5398a60cfd61607192d74ae8db237aaeaa07a98cd8ecdb8776c86eb87376ba3"
AUTH_USER="admin"
AUTH_PASSWORD="admin"
# Music folders (comma-separated paths)
# Example: /Users/youruser/Music,/Volumes/External/Music
MUSIC_FOLDERS="/Users/youruser/Music,/Volumes/External/Music"Then start:
pnpm build && pnpm start # Production
# or
pnpm dev # Development mode| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | SQLite database path. Use file:/data/tagr.db in Docker or file:./data/tagr.db locally. |
AUTH_SECRET |
Yes | Secret for signing JWT sessions. Generate with openssl rand -hex 32. |
AUTH_USER |
Yes | Login username. |
AUTH_PASSWORD |
Yes | Login password (plain text). |
MUSIC_FOLDERS |
No | Comma-separated list of paths to music directories. Defaults to /music if not set. |
PUID |
No | User ID for the container process. Defaults to 1000. (Docker only) |
PGID |
No | Group ID for the container process. Defaults to 1000. (Docker only) |
| Container Path | Purpose |
|---|---|
/data |
SQLite database. Persist with a named volume to avoid data loss. |
/music/* |
Mount points for your music libraries. |
Browser (React Query) --> Next.js API Routes --> Prisma --> SQLite
|
node-taglib-sharp --> audio files on disk
| Layer | Technology |
|---|---|
| Frontend | React 19, TanStack Query, Shadcn UI, Tailwind CSS 4 |
| Backend | Next.js 16 App Router (route handlers) |
| Database | SQLite via Prisma 7 + LibSQL |
| Auth | NextAuth 5 (credentials provider, JWT sessions) |
| Metadata Read | music-metadata |
| Metadata Write | node-taglib-sharp |
| Audio Player | WaveSurfer.js |












