cheat sheet
beets Music Organizer
Importing, tagging, querying, and organizing a music library with beets — config, plugins, queries, and common workflows on Windows.
beets Music Organizer
What it is
beets is a free, open-source command-line music library manager written in Python and maintained at beets.io. It auto-tags audio files by matching them against the MusicBrainz database, renames and moves them into a configurable folder structure, and exposes a powerful query language for searching, filtering, and reporting on your collection. Reach for beets when you want fully automated, metadata-accurate music organization from the terminal, with a plugin ecosystem covering art fetching, lyrics, acoustic fingerprinting, and more.
What's new in 2026
beets is in active development — three minor releases shipped between April and May 2026 (current line is v2.11.x, see the release page for exact numbers):
- Python 3.14 is now officially supported (added in v2.9.0).
- A new Tidal plugin fetches metadata directly from Tidal alongside MusicBrainz (v2.11.0).
- The
fetchartplugin now accepts WebP album art. - Portable library paths — beets can store paths relative to the library root, so your DB survives moving the library between drives or platforms (v2.10.0).
- The
webplugin patched a stored-XSS vulnerability in unescaped metadata fields. Upgradebeets[web]if you expose the built-in HTTP server. - The
smartplaylistplugin gained adest_regenoption to rewrite item paths when generating playlists, andsplupdateoutput was restructured. beet importcan now fall back toffprobeto detect the format of extensionless input files instead of skipping them.
Upgrade in place: pip install -U beets (or pipx upgrade beets if you installed with pipx — the recommended path on modern Windows).
Install
Via pip (Python 3.8+):
pip install beets
Install with common optional dependencies in one shot:
pip install beets requests pylast pyacoustid chromaprint
Verify:
beet --version
Output:
beets version 2.0.0
Python version 3.12.3
Configuration file
beets reads %APPDATA%\beets\config.yaml on Windows.
Open or create it:
beet config -e
Minimal working config:
# %APPDATA%\beets\config.yaml
directory: ~/Music/Library
library: ~/Music/beets.db
import:
move: yes # move files into directory (use copy: yes to keep originals)
write: yes # write tags to files after importing
log: ~/Music/import.log
ui:
color: yes
plugins:
- fetchart
- embedart
- lyrics
- lastgenre
- duplicates
- missing
- info
- edit
Path format (how files are organized under directory):
paths:
default: $albumartist/$year - $album%auniq{}/$track - $title
singleton: Non-Album/$artist - $title
comp: Compilations/$year - $album%auniq{}/$track - $title
Import music
Import a folder — beets looks up tags on MusicBrainz interactively:
beet import "C:\Users\Jay\Downloads\NewMusic"
Output (interactive):
Tagging:
The Beatles / Abbey Road
URL: https://musicbrainz.org/release/d6dc93a4-b294-4dc8-8d7c-f430c9bd09bc
(Similarity: 99.5%) (Tracks: 17, Score: 100%)
* 01 Come Together -> 01 Come Together
* 02 Something -> 02 Something
...
Apply, More candidates, Skip, Use as-is, as Tracks, Group albums,
Enter search, enter Id, aBort? [A]
Import without asking (auto-select best match):
beet import -A "C:\Users\Jay\Downloads\NewMusic"
Import and copy files instead of moving:
beet import -c "C:\Users\Jay\Downloads\NewMusic"
Import a single file as a singleton (not part of an album):
beet import -s "C:\Users\Jay\Downloads\song.mp3"
Re-import existing library items (re-tag from MusicBrainz):
beet import -L
Import without writing any tags (just add to database):
beet import -W "C:\Path\To\Music"
Query the library
List everything:
beet list
Output:
The Beatles - Abbey Road - Come Together
The Beatles - Abbey Road - Something
Radiohead - OK Computer - Paranoid Android
Radiohead - OK Computer - Karma Police
...
Search by artist:
beet list artist:radiohead
Search by album:
beet list album:"ok computer"
Search by year range:
beet list year:1990..2000
Search by genre:
beet list genre:jazz
Multiple conditions (AND by default):
beet list artist:beatles year:1969
Regex match:
beet list "title::^(Come|Something)"
Items without album art:
beet list -a artworks:0
List albums (one line per album):
beet list -a artist:radiohead
Output:
Radiohead - The Bends (1995)
Radiohead - OK Computer (1997)
Radiohead - Kid A (2000)
Radiohead - Amnesiac (2001)
Print specific fields:
beet list -f '$artist - $album ($year)' artist:beatles
Output:
The Beatles - Please Please Me (1963)
The Beatles - With the Beatles (1963)
The Beatles - A Hard Day's Night (1964)
Count results:
beet list artist:beatles | Measure-Object -Line
Modify tags
Change a field on matching items:
beet modify artist:"The Beatles" genre="Classic Rock"
Fix a wrong year on an album:
beet modify -a album:"Abbey Road" year=1969
Clear a field:
beet modify title:"Bad Title" title=""
Open items in an interactive editor (requires edit plugin):
beet edit artist:radiohead
Update & move files
Re-tag and move files to match current config paths:
beet move artist:radiohead
Move everything (reorganize after a path format change):
beet move
Re-write tags to disk without moving:
beet write artist:beatles
Update the database after manually editing tags outside beets:
beet update
Remove items
Remove a track from the library (database only, keeps the file):
beet remove title:"Come Together"
Remove and delete the file from disk:
beet remove -d title:"Come Together"
Remove an entire album:
beet remove -a album:"Abbey Road"
Plugins
Enable plugins in config.yaml under the plugins: key, then configure each below it.
fetchart — download album artwork
Automatically downloads cover art from sources like iTunes, Amazon, and Last.fm and saves it as a cover.jpg alongside the album files. Run beet fetchart at any time to fill in art for albums that were imported without it.
plugins:
- fetchart
fetchart:
auto: yes
minwidth: 500
quality: 90
sources: filesystem coverart itunes amazon lastfm wikipedia
Fetch art for items that are missing it:
beet fetchart
Force re-fetch all art:
beet fetchart -f
embedart — embed art into audio files
Reads the cover art file from the album folder (fetched by fetchart) and writes it into each audio file's metadata tags so it is visible in all players, not just those that read folder art. Use both fetchart and embedart together for full coverage.
plugins:
- embedart
embedart:
auto: yes
compare_threshold: 100
Embed art from the folder into all files in the library:
beet embedart
lyrics — fetch and store lyrics
Searches Genius, Musixmatch, and other sources for song lyrics and stores them in the lyrics field of the beets database (and optionally the file tags). Useful for offline lyric display in players that read embedded tags.
plugins:
- lyrics
lyrics:
auto: yes
fallback: ""
sources: genius musixmatch tekstowo
Fetch lyrics for everything:
beet lyrics
Fetch lyrics for a specific artist:
beet lyrics artist:radiohead
lastgenre — set genre from Last.fm tags
Queries the Last.fm API for crowd-sourced genre tags associated with the artist or album and writes the best match into the genre field. More accurate than MusicBrainz genre data for popular music; requires the pylast package.
plugins:
- lastgenre
lastgenre:
auto: yes
count: 1
prefer_specific: yes
source: album
Apply genres to untagged items:
beet lastgenre
duplicates — find duplicate tracks
Identifies tracks that share the same artist and title (or a configurable fingerprint) across the library, reporting both copies so you can decide which to keep. Useful after merging two collections or after re-importing files that were already present.
plugins:
- duplicates
List duplicates (same artist + title):
beet duplicates
Output:
The Beatles - Abbey Road - Come Together [/Music/Library/...]
The Beatles - Abbey Road - Come Together [/Music/Inbox/...]
Delete duplicate copies (keeps first found):
beet duplicates -d
missing — find incomplete albums
Compares the number of tracks you have for each album against the MusicBrainz total track count and reports albums where tracks are missing. Useful for auditing a library and prioritizing what to source.
plugins:
- missing
Show albums with fewer tracks than MusicBrainz reports:
beet missing
Output:
The Beatles - Abbey Road (17/17) — OK
Radiohead - OK Computer (12/12) — OK
Pink Floyd - The Wall (26/26) — OK
Radiohead - The Bends (12/12) — OK
acousticbrainz / bpd — BPM and key detection
bpd turns beets into a lightweight MPD-compatible music server, letting any MPD client (ncmpcpp, Cantata, etc.) browse and play the beets library. Use it when you want library-aware playback without exporting playlists.
plugins:
- bpd
Play music from the library via MPD protocol (requires an MPD client):
beet bpd
info — inspect a file's tags
Prints all metadata fields beets reads from a file — both embedded tags and beets database fields — without modifying anything. Use it to diagnose why a track is tagged incorrectly or to verify that embedart wrote the expected fields.
plugins:
- info
Show all tags for a file:
beet info "C:\Music\song.mp3"
Output:
albumartist: The Beatles
album: Abbey Road
title: Come Together
track: 1
tracktotal: 17
year: 1969
genre: Rock
mb_albumid: d6dc93a4-b294-4dc8-8d7c-f430c9bd09bc
mb_trackid: 84c8f3da-a0a2-4573-8dc4-fae33f00e92e
Statistics & reporting
Count items in the library:
beet stats
Output:
Tracks: 4,312
Total time: 12.2 days
Approximate total size: 38.41 GB
Artists: 283
Albums: 521
Album artists: 217
List all artists:
beet list -a | ForEach-Object { $_ -replace " - .*", "" } | Sort-Object -Unique
Albums sorted by year:
beet list -a -f '$year $albumartist - $album' | Sort-Object
Scripting with beet
Export library as JSON (useful for external tooling):
beet ls -f json > library.json
Print all file paths (for piping to other tools):
beet list -p
Output:
C:\Users\Jay\Music\Library\The Beatles\1969 - Abbey Road\01 - Come Together.flac
C:\Users\Jay\Music\Library\The Beatles\1969 - Abbey Road\02 - Something.flac
...
Pipe paths to foobar2000 or any player:
beet list -p artist:radiohead | Out-File -Encoding UTF8 playlist.m3u
Full config.yaml reference
directory: ~/Music/Library
library: ~/Music/beets.db
import:
move: yes
write: yes
log: ~/Music/import.log
autotag: yes
timid: no # set yes to confirm every import even with high-confidence match
match:
strong_rec_thresh: 0.10 # auto-accept matches below this distance
medium_rec_thresh: 0.25
max_rec:
missing_tracks: medium
unmatched_tracks: medium
paths:
default: $albumartist/$year - $album%auniq{}/$track - $title
singleton: Non-Album/$artist - $title
comp: Compilations/$year - $album%auniq{}/$track - $title
ui:
color: yes
plugins:
- fetchart
- embedart
- lyrics
- lastgenre
- duplicates
- missing
- info
- edit
fetchart:
auto: yes
minwidth: 500
sources: filesystem coverart itunes amazon lastfm
embedart:
auto: yes
lyrics:
auto: yes
sources: genius musixmatch
lastgenre:
auto: yes
count: 1
prefer_specific: yes
Common workflows
First-time library setup
# 1. Edit config
beet config -e
# 2. Import entire music folder
beet import "C:\Users\Jay\Music\Inbox"
# 3. Fetch missing art
beet fetchart
# 4. Embed art into files
beet embedart
# 5. Tag genres
beet lastgenre
# 6. Fetch lyrics
beet lyrics
# 7. Check for duplicates
beet duplicates
Add new downloads
# Download with yt-dlp, then import
yt-dlp -x --audio-format flac -o "C:\Music\Inbox\%(uploader)s - %(title)s.%(ext)s" "URL"
beet import -A "C:\Music\Inbox"
Fix bad tags before import
Open the file in the interactive editor before beets touches it:
beet import "C:\Music\Inbox\album"
# When prompted, choose 'e' to edit candidates, or 'i' to enter a MusicBrainz ID manually
Troubleshooting
| Problem | Fix |
|---|---|
No candidates found | Run beet import without -A, choose Enter search or enter Id to supply a MusicBrainz ID manually |
| Files not moving | Check import: move: yes in config; also verify beets has write permission to directory |
| Art not embedding | Enable both fetchart and embedart; run beet fetchart then beet embedart |
| Duplicate entries after re-import | Run beet duplicates -d to clean up; then beet update |
| Config not found | Run beet config -p to see the expected path |
| Unicode filenames broken | Ensure terminal is UTF-8; add PYTHONUTF8=1 to your environment variables |