Point Grape at a folder of music. It walks the tree, reads the tags, caches what it found, and gives you artists, albums, genres and folders to browse through — no account, no server, no network call unless you ask for one. It is a single binary built on iced and rodio, distributed through Colony.
Status: the scan → cache → browse → play loop is what Grape is used for daily, and it is the part covered by tests: scanning, tag reading, album-artist inference, the
.grape_cacheround trip, Last.fm parsing and backoff, playlist manipulation, and preference clamping and migration. The UI browsing, search, filters, tabs and FR/EN strings still need interactive testing. CI builds and runs tests on Linux, Windows and macOS; tests requiring a real audio device are explicitly ignored there. Native media sessions have state tests and an opt-in MPRIS round-trip test on an isolated D-Bus session. Linux is the platform exercised locally; Windows system controls still need interactive validation on Windows. Three audio preferences are inert: crossfade, automix and volume normalization persist and change nothing you can hear. The update settings have no updater behind them — Colony delivers updates. Opus, AIFF and WMA files are scanned into the library and then fail to decode.
Most local players ask you to import your music into their world first. Grape treats the folder on disk as the truth and everything else as a cache you can delete.
- Your folder layout is the library.
Artist/Album/Trackworks, albums sitting at the root work, loose files at the root work. No music file is moved, renamed or rewritten, and by default Grape writes nothing into the music folder: its cache lives in the Colony cache directory. Delete the cache, or point it elsewhere in preferences, and nothing is lost but a rescan. - Nothing leaves the machine by default. The only network call is Last.fm album enrichment, and it stays off until you paste in your own API key.
- Rescans are cheap. Every track is cached under a size + mtime signature, so a second scan only touches what changed.
- Tags lose to you. A genre or year you set by hand on an album outranks both the file's tags and anything Last.fm returns.
┌──────────────────────────────────────────────────────────────┐
│ Artists Genres Albums Folders [search] ≡ │
├───────────────┬──────────────────┬───────────────────────────┤
│ │ │ │
│ Artists │ Albums │ Tracks │
│ │ │ │
├───────────────┴──────────────────┴───────────────────────────┤
│ ◀◀ ▶ ▶▶ ──────●──────────── 1:42 / 4:05 ♪ │
└──────────────────────────────────────────────────────────────┘
The ≡ button opens the menu that holds Library, Playlist, Queue, Preferences and the four search toggles.
Library
- Scans a root folder given on the command line, or the one saved in
preferences (default
~/Music). - Reads tags with lofty: title, artist, album artist, compilation flag, duration, bitrate, codec, year, genre, embedded cover art.
- Works out the album artist for root-level albums: a compilation flag gives
Various Artists, otherwise a shared
ALBUMARTIST, otherwise a sharedARTIST. - Caches a track index, per-folder entries, cover art and metadata in the Colony cache directory, outside the music folder, and invalidates per track on size and modification time.
- Picks cover art from the album folder first (
cover,folder,front,artwork,albumas.jpg,.jpeg,.png,.webp), then the embedded picture, then whatever the last scan cached. - Optionally fills in missing album genre and year from Last.fm, with your own API key, a TTL cache and backoff when the API pushes back.
Playback
- Play, pause, seek, next, previous, shuffle, repeat, playback speed from 0.5× to 2×.
- Gapless playback: the next track is queued into the output half a second before the current one ends.
- A 3- or 5-band equalizer with Flat, Bass, Treble, Vocal and Custom presets, clamped to ±12 dB.
- Quiet / Normal / Loud output levels, and a configurable sample rate that falls back to the system default — with a visible notice — when the device refuses it.
Browsing
- Four tabs — Artists, Genres, Albums, Folders — over a three-column layout, with a player bar along the bottom.
- Search with accent-insensitive matching, widened on demand to also match genre, year, duration or codec. The ordering is fixed (by album, then track number) — the four sort modes exist in the code but no control reaches them.
- A full-screen queue split into now playing and up next, and playlists you can create, rename, delete and reorder.
- A mini-player mode that collapses the window down to the player bar alone.
- Keyboard control inside the window (arrows,
Tab,Enter,Space,n,p,+/-,m) and three global hotkeys —Ctrl+Alt+P,Ctrl+Alt+←,Ctrl+Alt+→— once Advanced shortcuts is enabled in Preferences.
Around the edges
- Opt-in desktop notifications, a tray icon and autostart, each one disabling itself when the platform says it is unavailable.
- Native system media controls: MPRIS 2 on Linux (including DMS) and SMTC on Windows. The system panel displays the current track, artist, album, cover and timeline, and can play, pause, stop, skip and seek. Linux also exposes volume and playback rate; Windows supports rate requests when offered by the system client. This works independently of tray and notification preferences.
- French and English interface, picked from the system locale.
- Session resume: track, position, tab and queue index come back on the next launch.
- Themes from Colony's shared palette catalog, defaulting to Catppuccin Mocha, with an automatic light or dark counterpart when following the system theme.
Media sessions follow the track actually playing, even while browsing another album. Commands remain available while paused without an extra polling timer. Metadata and cover references update only when the track changes; regular Linux position updates do not broadcast D-Bus signals. Covers stay local. If the OS media service is unavailable, Grape logs the failure and keeps playing normally. The exact controls shown depend on the desktop or Windows client. macOS system media controls are not implemented.
Files that actually decode: MP3, FLAC, WAV, OGG Vorbis, M4A/AAC. The scanner
also accepts .opus, .aif, .aiff and .wma; those appear in the library and
fail at playback, because the decoders compiled in do not cover them.
Install Colony, open the Multimedia category and install Grape. Updates arrive through the launcher, and because releases are signed, Colony verifies the signature before installing.
Grab the asset for your platform from the
latest release. Each
one ships with a matching .sig, .meta and .meta.sig.
| Platform | Asset |
|---|---|
| Linux (x86_64) | grape-linux |
| Windows (x86_64) | grape-windows.exe |
| macOS (Apple Silicon) | grape-macos |
| macOS (Intel) | grape-macos-x86 |
There is no installer: download the asset and run it.
The .sig and .meta.sig files are Colony's own ed25519 signatures. The
binaries are not signed by Apple or Microsoft, so macOS and Windows warn on
first launch.
-
Linux:
chmod +x grape-linux && ./grape-linux -
macOS: make it executable and clear the download quarantine flag, then run it:
chmod +x grape-macos xattr -d com.apple.quarantine grape-macos ./grape-macos
Use
grape-macos-x86on Intel Macs. If you skip thexattrstep, macOS 15 and later block the first launch; allow it under System Settings > Privacy & Security > Open Anyway. -
Windows: if SmartScreen shows "Windows protected your PC", click More info > Run anyway.
Releases are cut by release-please when its release pull request is merged, not
on every merge to main.
git clone https://github.com/Project-Colony/Grape
cd Grape
cargo build --releaseRequires Rust 1.90 or newer. On Linux you also need libasound2-dev and
pkg-config for the audio backend, plus clang and lld — the repository pins
the Linux linker to clang -fuse-ld=lld, and without them the build fails at
link time in a way that looks like a Rust problem and is not.
Run it against a specific folder:
cargo run --release -- /path/to/libraryWith no argument, Grape uses the library folder from preferences.
Run the regular suite with cargo test. On Linux, the native media checks can
also exercise a private session bus and a real audio output device:
dbus-run-session -- cargo test --lib mpris_round_trip -- --ignored
cargo test --test player_tests -- --ignored
cargo test --lib preloaded_track -- --ignoredEverything is in docs/; start at the index, docs/README.md.
| docs/guide/install.md | getting it running, and where it puts its files |
| docs/guide/usage.md | the interface, end to end |
| docs/guide/configuration.md | every preference, including the ones that do nothing |
| docs/guide/troubleshooting.md | no sound, no tray, no genres, no hotkeys |
| docs/internals/architecture.md | how the modules fit together |
| docs/internals/contributing.md | building, testing, and what the hooks check |
| docs/internals/packaging.md | how a release is built and signed |
| docs/project/roadmap.md | what is done and what is next |
Free code signing provided by SignPath.io, certificate by SignPath Foundation.
Windows builds are Authenticode-signed this way once the SignPath Foundation has accepted the project; until then they ship without Authenticode. Every release asset, on every platform, is always signed with the Project-Colony ed25519 release key, and Colony verifies that signature before installing.
Team roles and members:
- Committers and reviewers: MotherSphere
- Approvers: MotherSphere
Grape contacts one networked service, Last.fm, and only after you have turned it on yourself. Nothing else ever leaves your machine: there is no telemetry, no analytics, no account and no update check.
- What turns it on. Putting your own Last.fm API key into
preferences.json(metadata_api_key). The key is empty by default and there is no field for it in Preferences; with no key, Grape makes no network request at all. - When. With a key set, Grape asks Last.fm's
album.getInfo(https://ws.audioscrobbler.com/2.0/) for the album you select, directly or through its artist, genre or folder, unless it already holds an answer for that album younger than the cache lifetime (24 hours by default), and again when you press Enrich on an album. - What is sent. Your API key, the album's artist and title, and a
Grape/<version>user agent. Like any HTTPS request, it also shows Last.fm your IP address. Last.fm's answer (genre and year) is cached on your machine.
GPL-3.0-or-later © 2026 MotherSphere
You may redistribute and modify Grape under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
