Tagr
Self-hosted web app for browsing, playing, and editing music file metadata. Features a three-panel UI to navigate your library, listen to tracks, and write tag changes directly back to audio files. Built with Next.js, React, Prisma + SQLite, and node-taglib-sharp.
Install / Use
/learn @suitux/TagrREADME
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.

Features
Metadata Editing
- 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)

Change History
- 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

Music Player
- 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
Library Browsing
- 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
File Support
| 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.
Mobile Support
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)
Additional
- 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

Quick Start with Docker
1. Clone the repository
wget https://raw.githubusercontent.com/suitux/Tagr/main/docker-compose.yml
2. Generate a secret key
openssl rand -hex 32
Copy the output — you'll use it as AUTH_SECRET in the next step.
3. Configure docker-compose.yml
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).
4. Build and run
docker compose up -d
5. Open your browser
Navigate to http://localhost:3000, log in with your credentials, and hit the scan button to index your library.
Manual Installation
Requirements: Node.js 22+.
git clone https://github.com/suitux/Tagr.git
cd tagr
pnpm install
Create 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
Environment Variables
| 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) |
Docker Volumes
| Container Path | Purpose |
|----------------|---------|
| /data | SQLite database. Persist with a named volume to avoid data loss. |
| /music/* | Mount points for your music libraries. |
Architecture
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 |
License
MIT
