A CLI for syncing a music library to a classic iPod from a modern Mac — no iTunes required.
Handles the full workflow: scan and clean up your library's metadata, interactively pick what goes on the iPod, and sync — all with a modern terminal UI.
pipx install clickwheelTo use clickwheel fix (metadata cleanup, album art, genre tagging):
pipx inject clickwheel 'clickwheel[fix]'Create a config file pointing to your music library:
mkdir -p ~/.clickwheel
cat > ~/.clickwheel/config.yaml << 'EOF'
music_dir: /path/to/your/music
EOFThen run clickwheel scan to index your library and clickwheel select to start picking music for your iPod.
Commands like select, edit, diff, and sync automatically check for library changes before running. To skip this, pass --no-scan.
| Command | Description |
|---|---|
clickwheel scan |
Index your music library and report on metadata quality |
clickwheel fix |
Clean up metadata, fetch album art, fill genres via beets |
clickwheel select |
Interactive picker — checkbox artist selection |
clickwheel playlist |
List saved playlists or show details for one |
clickwheel edit |
Add or remove artists via interactive menus or --add/--remove flags |
clickwheel delete |
Delete a saved playlist (with confirmation) |
clickwheel diff |
Preview what would be added or removed on the iPod |
clickwheel sync |
Push your playlist to the iPod (with live progress table) |
clickwheel ls |
Show what's on the iPod |
clickwheel eject |
Safely unmount the iPod |
clickwheel scrobble |
Submit recent iPod listens to Last.fm |
clickwheel reads from ~/.clickwheel/config.yaml:
music_dir: /Volumes/Music/Library
ipod_capacity_gb: 64 # defaults to 64
auto_scan: true # auto-check for library changes (default: true)
auto_scan_staleness_minutes: 30 # how often to re-check (default: 30)
lastfm_api_key: your_key # last.fm/api/account/create
lastfm_api_secret: your_secret
lastfm_username: your_usernameEnvironment variables (MUSIC_DIR, AUTO_SCAN, etc.) override the config file.
clickwheel fix uses beets to fetch album art, fill genres, and clean up tags. Install the extras first:
# If installed with pipx:
pipx inject clickwheel 'clickwheel[fix]'
# If installed with pip:
pip install 'clickwheel[fix]'On first run, clickwheel generates a beets config at ~/.clickwheel/beets/config.yaml. You can edit it to customize sources, matching thresholds, etc. The config is set up to never move or rename your files.
Fix a single artist/album folder:
clickwheel fix "Artist - Album Name"Or fix the entire library:
clickwheel fixTo submit your iPod listens to Last.fm, add your API credentials to the config (get them at last.fm/api/account/create):
lastfm_api_key: your_key
lastfm_api_secret: your_secret
lastfm_username: your_usernameThen authorize clickwheel with your Last.fm account (one-time):
clickwheel scrobble --authAfter that, submit listens any time your iPod is connected:
clickwheel scrobbleScrobbles are cached locally so duplicates are never submitted, even if you run it multiple times.
- macOS (iPod sync depends on macOS disk utilities)
- Python 3.11+
- iPod Classic with stock firmware, connected via USB
- FLAC files are excluded from sync (stock firmware limitation)
See CONTRIBUTING.md for dev setup, testing, and commit conventions.