duckd is a lightweight desktop audio manager. it provides global hotkey volume presets, a per-application mixer, and lives in your tray.
- global hotkeys for volume presets, including while the main window is hidden
- per-application volume mixer for currently active audio streams
- optional default volume for every stream not explicitly listed in a preset
- system tray controls and close-to-tray behaviour
- optional start-with-system support on windows and linux
- signed in-app updates from github releases
- editable, human-readable .toml configuration
- config import and export
download the latest release from the website or from the releases page.
git clone https://github.com/ai9an/duckd.git
cd duckdinstall node.js, rust, and the tauri v2 prerequisites, then run:
npm install
npm run tauri devcreate a linux appImage:
npm run bundle:linuxcreate MSI and NSIS installers for windows:
npm run bundle:windows- open presets and select new preset.
- give the preset a name and record a global hotkey.
- choose running applications and set their target volumes.
- optionally set a default volume for all other active streams.
- save the preset and use its shortcut from any application.
applications are matched by process or executable name. a preset silently skips applications that are not currently running, and explicitly listed targets override its default stream volume.
per-application microphone volume is not exposed and therefor cannot be used on windows
duckd uses .toml for a readable config system.
[general]
run_in_tray = true
hud_hotkey = "Ctrl+Shift+Space"
[[presets]]
name = "lockin"
hotkey = "Alt+3"
default_volume = 75
[[presets.targets]]
app = "vesktop.bin"
volume = 20
[[presets.targets]]
app = "spotify"
volume = 0
[[presets.targets]]
app = "firefox-bin"
volume = 0
duckd checks the latest published github release once at startup and can also check from settings. it always asks before downloading and installing an update. builds made before updater support was added cannot update themselves retroactively.
tauri requires every updater artifact to be signed. generate the long-lived updater key once and keep the private key backed up somewhere secure:
npm run tauri signer generate -- -w ~/.tauri/duckd.keyadd these repository secrets before pushing a release tag:
TAURI_SIGNING_PRIVATE_KEY: the private key contentsTAURI_SIGNING_PRIVATE_KEY_PASSWORD: the private-key password, or an empty valueTAURI_UPDATER_PUBLIC_KEY: the generated public key contents
keep the versions in package.json, src-tauri/Cargo.toml, and src-tauri/tauri.conf.json identical, then push a semantic version tag such as v1.2.0. the release workflow builds signed windows x64 NSIS and linux x64 AppImage artifacts, publishes them, and generates latest.json for installed clients.
tauri v2rustvanilla typeScript and vitewindows-volume-controlon windowspulsectlon linux
