Settings & Files
Where things live
Oxidify follows each platform’s conventions. On Linux:
| What | Where | Safe to delete? |
|---|---|---|
| Settings | ~/.config/oxidify/settings.json |
Yes, you lose preferences |
| Winamp skins | ~/.config/oxidify/skins/ |
Yes, you add them again |
| Shared Web API sign-in | ~/.local/state/oxidify/shared_web_api_token.json |
Yes, you sign in again |
| Personal Web API sign-in | ~/.local/state/oxidify/personal_web_api_token.json |
Yes, personal acceleration is removed |
| Playback credential | ~/.local/state/oxidify/credentials/ |
Yes, you approve playback again |
| Last playback volume | ~/.local/state/oxidify/volume/ |
Yes |
| Proxy password | ~/.local/state/oxidify/credentials/proxy-password |
Yes, you type it again |
| YouTube cookies for yt-dlp (optional, youtube.com entries only) | ~/.local/state/oxidify/credentials/youtube-cookies.txt |
Yes, you add them again |
| Per-run copies of those cookies (owner-only, emptied when alternate playback starts) | ~/.local/state/oxidify/credentials/youtube-cookies-scratch/ |
Always |
| Last session | ~/.local/state/oxidify/session.json |
Yes |
| Audio cache | ~/.cache/oxidify/audio/ |
Always |
| Artwork cache (trimmed to 256 MiB at each start, oldest first) | ~/.cache/oxidify/art/ |
Always |
| Lyrics cache | ~/.cache/oxidify/lyrics/ |
Always |
| Account-tagged Top songs cache (six-hour lifetime, at most 1 MiB) | ~/.cache/oxidify/top-tracks.json |
Always |
| Account-scoped playlist cache (shown first, then revalidated; at most 32 MiB per playlist; Settings can clear it) | ~/.cache/oxidify/playlists/<account-id>/ |
Always |
| Account-scoped library snapshot (the playlist list and Liked Songs as last seen, at most 32 MiB each; Settings can clear it) | ~/.cache/oxidify/library/<account-id>/ |
Always |
| Last run’s log | ~/.local/state/oxidify/oxidify.log |
Always |
| Crash log | ~/.local/state/oxidify/panic.log |
Always |
Bundled yt-dlp, its cache, and the scratch folder it unpacks into (bin/ytdlp-tmp/, emptied whenever alternate playback starts) |
~/.local/state/oxidify/bin/ |
Yes; the app extracts it again |
| Alternate audio match memory (video ids and stream URLs, bounded) | ~/.local/state/oxidify/bin/alternate-matches.json |
Always |
| Listening history (the plays counted on this computer, one line each) | ~/.local/state/oxidify/history/<account-id>.jsonl |
Yes; the Your listening page can clear it too |
Clearing caches never signs you out; credentials live in state, not cache. Web API token files are written with owner-only permissions. Signing out from Settings deletes both Web API grants and the separate playback credential. The proxy password and YouTube cookies stay until you remove them in Settings.
On macOS, settings, state, and the logs are in
~/Library/Application Support/me.master0ffate.oxidify and the caches in
~/Library/Caches/me.master0ffate.oxidify. On Windows, settings are in
%APPDATA%\master0ffate\oxidify\config, state and the logs in
%LOCALAPPDATA%\master0ffate\oxidify\data, and the caches in
%LOCALAPPDATA%\master0ffate\oxidify\cache.
Fastpotify, the project Oxidify is derived from, kept its files in
fastpotify directories next to these. The first run after switching
imports settings, sign-ins, skins, and playback credentials from there,
once; the old directories are left untouched. An empty fastpotify-imported
file in the state directory records that the import ran, so signing out or
deleting a file here never brings the Fastpotify copy back.
settings.json
Settings are stored in one readable JSON file and written atomically. UTF-8
files saved with a leading byte order mark by a Windows editor are accepted
without resetting preferences. A field with a value Oxidify cannot use falls
back to its default while the other fields are kept, and the file as it was
is copied to settings.json.bad next to it first. Its main fields are:
| Field | Default | Meaning |
|---|---|---|
device_name |
Oxidify |
Name on Spotify Connect |
bitrate |
320 |
96, 160, or 320 kbps |
normalisation |
false |
Volume normalisation |
autoplay |
true |
Keep playing similar music at the end |
gapless |
true |
Gapless playback |
audio_backend |
platform | pulseaudio or rodio on Linux |
audio_cache_mb |
1024 |
On-disk audio cache budget |
theme |
dark |
dark, light, or system |
accent |
blue |
The accent colour: blue or green |
accent_from_art |
true |
Tint pages with album art |
zoom |
1 |
Interface zoom; Ctrl+plus and Ctrl+minus change it |
sidebar_visible |
true |
Your Library is shown |
sidebar_collapsed |
false |
Your Library is folded to a rail of covers |
sidebar_grid |
false |
Your Library shows a grid of covers |
compact_library |
false |
Your Library rows show names only |
compact_tracks |
false |
Track tables use one-line rows without covers |
winamp_window |
false |
The window is the Winamp mini player |
skin |
none | A file or folder name in the skins folder; the built-in skin when absent |
skin_scale |
by display | Screen pixels per skin pixel, 1 to 4 |
winamp_on_top |
false |
Keep the mini player above other windows |
vis |
bars |
The mini player’s visualiser: bars, scope, or off |
playlist_open |
false |
The playlist window is open under the mini player |
playlist_height |
174 |
The playlist window’s height in skin pixels |
eq_open |
false |
The equalizer window is open under the mini player |
eq_on |
false |
The equalizer shapes local playback |
eq_preamp_db |
0 |
The preamp, in decibels, never above zero |
eq_bands_db |
ten zeros | The bands from 60 Hz to 16 kHz, in decibels, -12 to 12 |
balance |
0 |
Left to right, -1 to 1, for local playback |
mono |
false |
Play both channels the same |
playlist_shaded |
false |
The playlist window is rolled up to its title bar |
winamp_shaded |
false |
The main window is rolled up to its title bar |
keep_playing_in_background |
true |
Close to tray |
check_for_updates |
true |
Ask GitHub once a day for a newer release |
discord_presence |
false |
Show the song playing on this computer as your Discord status |
web_client_id |
none | Optional personal Spotify app id used alongside shared coverage |
playback_backend |
spotify |
spotify (Connect / librespot) or alternate |
piped_api_base |
empty | Optional Piped-compatible YouTube fallback |
ytdlp_path |
empty | A user yt-dlp, used only if strictly newer than the official pin |
alternate_min_score |
0.55 |
Minimum match score; weaker hits are never played |
alternate_skip_on_miss |
true |
Skip forward when no match meets the score. Transient network errors retry; terminal transport and decode failures stop instead of skipping. |
proxy_mode |
system |
system (environment and platform settings), off (direct, always), http, or socks5 |
proxy_host |
empty | Host name or IP of a manual proxy, without scheme or port |
proxy_port |
empty | Port of the manual proxy |
proxy_username |
empty | Optional user for the Web API through the manual proxy |
Proxy settings
An http proxy covers everything Oxidify asks of the network: catalog and
playback control through the Web API, and the audio connection itself.
A socks5 proxy covers the Web API, artwork, lyrics and alternate
playback; the audio connection (librespot) only tunnels through HTTP, so
with socks5 Spotify playback connects directly. The proxy password is never written to settings.json; it lives alone in
credentials/proxy-password with owner-only permissions, and only the
Web API client carries it. The audio connection (librespot) cannot sign
in to a proxy, so an authenticating proxy blocks streaming unless it also
accepts anonymous connections.
A changed proxy is picked up the next time Oxidify starts. off ignores
environment variables and platform settings; system leaves them in
charge. Handing playback to a receiver on the local network always
connects to it directly.
Command line
oxidify [OPTIONS]
--device-name <NAME> Spotify Connect name for this session
-v, --verbose More logs from librespot and the API client
oxidify.log in the state directory is what to attach to a bug report:
it contains the last run’s output, including the additional lines printed by
oxidify -v. If the app crashed, attach panic.log from the same directory
as well.
Demo mode
Builds made with cargo build --features demo accept --demo, which fills
the interface with sample data, useful for screenshots, theming, and
interface work. Demo mode never writes settings.
--demo-page opens a page, such as home, playlist:pl1, or artist:art0,
and --demo-show adds surfaces on top of it: a comma separated list of
queue, now-playing, collapsed, grid, green, podcasts, devices,
shortcuts, jump, create, light, focus, login, winamp,
playlist, and eq.
--demo-shot <PATH> writes the window to a PNG and exits, which is how the
screenshots in these pages are made:
cargo run --release --features demo -- \
--demo-shot docs/screenshot.png --demo-page playlist:pl1 --demo-show now-playing
The shot is the window’s own frame buffer, so it comes out at whatever size
the window is. --demo-shot-delay <MS> sets how long cover art has to arrive
before the frame is taken.