A native Rust implementation of HTDemucs v4 — state-of-the-art music source separation. Splits any song into individual stems (drums, bass, vocals, etc.) using GPU-accelerated inference via Burn.
Runs as a native CLI (Metal on macOS, Vulkan on Linux/Windows), entirely in the browser via WebAssembly + WebGPU, or as a DAW plugin (VST3/CLAP, macOS) — no server, no uploads, fully local.
There Ain't Nothin'" by HoliznaCC0 (CC0 — public domain), separated with the standard htdemucs model:
| Original mix | there-aint-nothin.mp4 |
| Drums | drums.mp4 |
| Bass | bass.mp4 |
| Vocals | vocals.mp4 |
| Other | other.mp4 |
- Three model variants — Standard (4-stem), 6-Stem (adds guitar & piano), and Fine-Tuned (best quality)
- GPU accelerated — Metal, Vulkan, and WebGPU backends via Burn's wgpu support
- DAW plugin — VST3/CLAP instrument plugin with native macOS UI, MIDI-gated stem playback, and per-stem aux outputs
- Browser app — drag-and-drop web UI running 100% locally in your browser through WebAssembly
- Native CLI — fast command-line inference with progress tracking
- Spectrogram visualization — magma-colormap spectrograms with frequency axis labels
- Multi-track playback — solo, mute, and download individual stems in the web UI
The plugin runs as a VST3 or CLAP instrument in any DAW on macOS. Drop in an audio file, run separation, and play back individual stems — driven entirely by MIDI input.
Note: The plugin is currently macOS-only (native SwiftUI UI with Metal GPU inference).
Drop an audio file, pick a model, and run separation:
Per-stem mixer with spectrograms:
Drag stems directly into your DAW:
- Load audio — drag a file from your DAW or Finder into the plugin (WAV, AIFF, MP3, FLAC)
- Choose a model and click Run separation — model weights are downloaded automatically on first use and cached for future runs
- Play stems via MIDI — any MIDI note triggers playback, releasing all notes stops it. Playback always starts from beat 0 in the DAW
- Preview in the UI — use the built-in transport to audition stems without MIDI
- Main output is a stereo mix with per-stem gain sliders and solo buttons
- Solo isolates a stem in the main mix — hold Cmd and click to solo multiple stems
- Aux outputs provide the raw separated stems on dedicated stereo buses (Drums, Bass, Other, Vocals, Guitar, Piano), so you can route each stem to its own mixer channel in your DAW
Download Demucs.vst3 or Demucs.clap from the latest release and copy to:
- VST3:
~/Library/Audio/Plug-Ins/VST3/ - CLAP:
~/Library/Audio/Plug-Ins/CLAP/
The browser version compiles the full inference pipeline to WebAssembly and runs on your device using WebGPU. No audio is uploaded anywhere — everything stays local.
Note: The WebAssembly build is significantly slower than the native CLI due to WebGPU overhead and WASM constraints. For batch processing or long tracks, the CLI is recommended.
Drop an audio file:
Separation results with per-stem spectrograms:
| Model | Stems | Size | Description |
|---|---|---|---|
htdemucs |
drums, bass, other, vocals | 84 MB | Balanced speed and quality |
htdemucs_6s |
drums, bass, other, vocals, guitar, piano | 84 MB | Adds guitar and piano separation |
htdemucs_ft |
drums, bass, other, vocals | 333 MB | Fine-tuned — best quality, slower |
Model weights are downloaded automatically from Hugging Face on first use (both CLI and web).
demucs-swift packages the same
inference for iOS, macOS, tvOS, and visionOS apps, GPU-accelerated through
Metal. It is built from the demucs-ffi crate (UniFFI) and published by the
Release SDK Swift workflow whenever a swift-vX.Y.Z tag is pushed; the tag
must match the demucs-ffi crate version.
To build the XCFramework locally (macOS with Xcode, a stable toolchain with the
iOS/macOS targets, and a nightly with rust-src for tvOS/visionOS):
make swift-xcframeworkSeparate audio stems from a music file
Usage: demucs [OPTIONS] [INPUT]
Arguments:
[INPUT] Input audio file (WAV, AIFF, FLAC, MP3, OGG, M4A/AAC — stereo or mono, any sample rate)
Options:
-m, --model <MODEL> Model variant [default: htdemucs]
[possible values: htdemucs, htdemucs_6s, htdemucs_ft]
-s, --stems <STEMS> Stems to extract, comma-separated (e.g. "drums,vocals")
Available: drums, bass, other, vocals, guitar, piano
Default: all stems for the chosen model
-o, --output <OUTPUT> Output directory [default: ./stems/]
--debug Print layer-by-layer debug stats
--mcp Run as an MCP server over stdio
-h, --help Print help
# Separate all 4 stems
demucs song.mp3
# Extract only vocals
demucs song.mp3 -s vocals
# Use the 6-stem model, output to a custom directory
demucs song.flac -m htdemucs_6s -o ./my_stems/
# Best quality with the fine-tuned model
demucs song.wav -m htdemucs_ftdemucs --mcp speaks MCP over stdio
(newline-delimited JSON-RPC 2.0), so any MCP client can separate stems without
shelling out. stdout carries JSON-RPC only; logs go to stderr.
Generic client config:
{
"mcpServers": {
"demucs": { "command": "demucs", "args": ["--mcp"] }
}
}Tools:
separate_stems—{ input, model?, stems?, output_dir? }.inputandoutput_dirmust be absolute paths;output_dirdefaults to<input name>_stems/beside the input. Returns a text summary plusstructuredContentwith the written stem paths. Failures come back asisError: true. Send_meta.progressTokento receivenotifications/progress, andnotifications/cancelledto stop a run between chunks.list_models— model metadata plus acachedflag, so a client can warn before weights are downloaded.
One separation runs at a time; a second concurrent call returns a "busy" error. The last loaded model is kept in memory, so repeated calls skip weight loading and GPU init.
- Rust (stable toolchain)
- wasm-pack —
cargo install wasm-pack - Node.js and pnpm — for the web frontend
- A GPU with Metal (macOS), Vulkan (Linux/Windows), or WebGPU (browser) support
# Build the native CLI (release mode, auto-detects GPU backend)
make cli
# Run the CLI directly
cargo run -p demucs-cli --release -- song.mp3# Dev server with debug WASM (fast compile, slower inference)
make dev
# Dev server with release WASM (slow compile, fast inference)
make dev-release
# Production build
make web| Target | Description |
|---|---|
make plugin |
Bundle VST3 + CLAP plugin (release) |
make cli |
Build native CLI (release) |
make wasm |
Build WASM (debug) |
make wasm-release |
Build WASM (release, optimized) |
make dev |
WASM debug + Vite dev server |
make dev-release |
WASM release + Vite dev server |
make web |
Full production web build |
make swift-xcframework |
Build the demucs-swift XCFramework and bindings into dist/swift (macOS) |
make clean |
Remove all build artifacts |
cargo test -p demucs-core
cargo test -p demucs-ffidemucs-rs/
├── demucs-core/ Core ML inference library (model, DSP, weights)
│ Compiles to both native and wasm32-unknown-unknown
├── demucs-cli/ Native CLI binary (clap, symphonia, indicatif)
├── demucs-plugin/ DAW plugin — VST3/CLAP via nih-plug (macOS, SwiftUI editor)
├── demucs-wasm/ Thin wasm-bindgen adapter over demucs-core
├── demucs-ffi/ UniFFI bridge for the Swift SDK (demucs-swift)
├── uniffi-bindgen/ Generates the Swift bindings from demucs-ffi
├── web/ React + TypeScript frontend (Vite)
└── bench/ Python benchmark & validation suite
- Demucs by Meta Research — the original PyTorch implementation
- demucs.cpp — C++ reference that informed tensor shapes and computation order
- Burn — the Rust deep learning framework powering inference
Licensed under the Apache License, Version 2.0.




