Repository navigation
Releases: stemdeckapp/stemdeck
Release list
v0.5.0 Alpha 1
Before you install
If you have a previous version of StemDeck installed, delete these folders first using Finder before opening the new DMG:
~/Library/Application Support/StemDeck~/Library/WebKit/app.stemdeck.desktop~/Library/WebKit/stemdeck
In Finder, press ⌘ Shift G, paste each path, and move the folder to Trash. Then empty the Trash before installing.
What's new in 0.5.0 Alpha 1
A proper DAW look
The whole interface has been rebuilt around a flat dark DAW aesthetic. The mixer and waveform lanes now sit side by side in a two-column layout, with rows that dynamically fill the full available height no empty black gap when you load a track with fewer stems. Non-extracted stems are grayed out in both the mixer and waveform. Loop regions are shown as a full-height overlay so they're easy to spot.
Track info lives in the footer now
The album art, title, time position, stem count, and favorite button have moved to the footer always visible while the transport is running. Below that sits a scrub bar spanning the full width of the footer, plus elapsed / total time. When no track is loaded, the footer shows a decorative placeholder waveform.
Export Mix actually works
You can now export your current stem mix as a WAV or MP3 directly from the footer. The file lands as {title}_exported_mix.wav (or .mp3) no spaces, no special characters, just clean underscores. In the Tauri desktop app, exporting hands off to the system browser since WKWebView doesn't support standard download links. Export button stays grayed out until a track is loaded.
A subtle but important pipeline fix: previously, selecting all 6 stems meant no mix file was produced at all, so export would silently fail. That's fixed a mix is always built regardless of stem selection.
Footer waveform shows the real signal
The waveform in the footer used to pull from the first available stem (often vocals). On an instrumental section that meant a flat line. It now uses the full reconstructed mix, so what you see actually matches what you hear.
Tag search with autocomplete
Type # in the library search box to filter by tag. As you type, a dropdown shows up to 8 matching suggestions click one or navigate with arrow keys and Enter. Tags are extracted automatically from YouTube metadata.
Library sidebar
New sidebar sections: Recent, Stem Collections, Tags, and Favorites. Folders support subfolder nesting via drag-and-drop (circular nesting is blocked). Track cards show Extracted, Source, and Quality details. Purged tracks are remembered across reloads and never reappear.
Sections bar
An interactive sections bar sits above the waveform. You can add, rename, drag, and resize sections. Changes persist across restarts. A live saving indicator shows when a section edit is in-flight.
Analysis panel
The analysis cards now include Dynamic Range (DR) score with a label (Compressed / Moderate / High / Wide), Tempo Stability as a percentage, and a Key Confidence meter.
This is a pre-release alpha. Things may break. If you hit something, please open an issue.
Artifact scan
- Windows portable packages were scanned with ClamAV in CI before upload.
Artifact build
- macOS arm64 and x64 DMGs and runtime packs were built and inspected on a macOS Woodpecker agent before upload.
v0.4.0-alpha.3
v0.4.0-alpha.3
Important
macOS users run this after installing:
xattr -dr com.apple.quarantine /Applications/StemDeck.app
macOS Gatekeeper will block the app on launch without this step. Proper code signing is planned for a future release.
What's new in alpha.3
This release applies the papaya improvement cycle ÔÇö 11 fixes across the backend pipeline, frontend, and desktop setup flow.
Backend
Download retries on transient network errors
yt-dlp downloads now retry up to 3 with exponential backoff (2 / 4 / 8 s) on transient failures ÔÇö SSL errors, connection resets, DNS blips, timeouts. Non-retriable errors (404, private video, geo-block, age-restricted) still fail immediately with no retry.
Pipeline timeout constants
Hardcoded timeouts scattered across pipeline files (300 s for FFmpeg, 120 s for analysis, 1800 s for Demucs stall detection) are now named constants in config.py, overridable via environment variables (STEMDECK_TIMEOUT_FFMPEG, STEMDECK_TIMEOUT_ANALYZE, STEMDECK_TIMEOUT_DEMUCS_STALL).
Registry schema migration
The job registry now runs a _migrate() function on load that upgrades persisted schemas incrementally. The existing "version" field is now acted on ÔÇö adding or changing schema fields in future releases will not break already-completed jobs on restart.
Job correlation in logs
Every pipeline log line is now prefixed with [job_id], making it straightforward to trace a single job across the download  analyze  separate stages in log output.
Frontend
Client-side upload validation
File size and type are now validated in the browser before the upload begins. Files over 100 MB or with unsupported formats are rejected immediately with a toast ÔÇö no round-trip to the server needed.
Stem names from API
STEM_NAMES is no longer hardcoded in JavaScript. The frontend fetches the authoritative list from GET /api/config on startup, so adding or renaming a stem in the backend is reflected in the UI without a separate frontend change.
SSE race condition guard
SSE-driven state updates are now deferred by one tick (setTimeout(..., 0)) so in-progress user interactions (mixer moves, stem toggles) are not clobbered by a concurrent server-sent event.
localStorage error visibility
localStorage reads and writes that fail (e.g. quota exceeded) now emit a console.warn instead of being silently swallowed, making persistence failures visible during debugging.
Removed debug console.log
A leftover console.log call in player.js has been removed.
Replaced alert() with toast
Unsupported file type errors that previously used alert() now use the in-app showError() toast ÔÇö accessible, mobile-friendly, and consistent with the rest of the UI.
Desktop setup
Actionable error messages
Each terminal error state in the setup flow now includes a specific recovery hint and a working Retry button ÔÇö e.g. "Check that your disk has at least 2 GB free and click Retry" instead of a bare error string.
Artifact scan
- Windows portable packages were scanned with ClamAV in CI before upload.
Artifact build
- macOS arm64 and x64 DMGs and runtime packs were built and inspected on a macOS Woodpecker agent before upload.
v0.4.0-alpha.2
What's fixed in alpha.2
Important
macOS users run this after installing:
xattr -dr com.apple.quarantine /Applications/StemDeck.app
macOS Gatekeeper will block the app on launch without this step. Proper code signing is planned for a future release.
Python runtime (ModuleNotFoundError: No module named 'encodings')
The backend failed to start on any user machine because the bundled Python runtime was missing its standard library. The root cause was using python -m venv to build the runtime pack venvs only create site-packages/ and borrow stdlib from the build machine's Python prefix, which doesn't exist on user machines.
Fix: The runtime pack now bundles the full python-build-standalone (UV PBS) Python installation, which already contains the complete stdlib at lib/python3.12/. PYTHONHOME is set at launch to point Python to this bundled location.
Stale/broken runtime no longer blocks upgrade
If a broken runtime from a previous install was on disk, the app would detect the Python binary as "ready", skip re-extraction, and crash. probe_runtime now runs python -c "import encodings" to validate the stdlib is actually working before declaring the runtime healthy. A broken install triggers re-extraction automatically.
Native zstd extraction (fixes macOS Tahoe issue #31)
macOS ships bsdtar compiled without zstd support, causing runtime pack extraction to fail with Can't initialize filter; unable to run program 'zstd -d -qq'. Extraction now uses native Rust crates (zstd, tar, flate2) with no dependency on system tar or zstd binaries.
Setup retries stale cached archive
If a previously downloaded runtime archive fails SHA256 verification, the app now deletes it and re-downloads instead of showing a permanent error.
Artifact scan
- Windows portable packages were scanned with ClamAV in CI before upload.
Artifact build
- macOS arm64 and x64 DMGs and runtime packs were built and inspected on a macOS Woodpecker agent before upload.
v0.4.0-alpha.1
macOS Native App
StemDeck is now available as a native macOS application (.dmg) for both Apple Silicon and Intel Macs.
What's new
-
Native macOS app
Built with Tauri 2, including a first-launch setup wizard that automatically downloads and installs a self-contained backend runtime. No Python or system dependencies required. -
Apple Silicon acceleration (MPS)
Stem separation uses Metal Performance Shaders on M1 and newer Macs for significantly improved performance. -
arm64 + x64 builds
Separate native builds are available for both Apple Silicon and Intel architectures. -
Backend watchdog
The Python backend process is automatically terminated if the desktop shell exits unexpectedly.
Downloads
| File | Platform | Acceleration |
|---|---|---|
StemDeck-macOS-arm64.dmg |
macOS Apple Silicon (M1/M2/M3/M4) | Metal (MPS) |
StemDeck-macOS-x64.dmg |
macOS Intel | CPU |
StemDeck-Windows-x64.zip |
Windows | CPU |
StemDeck-Windows-x64.NVIDIA.zip |
Windows + NVIDIA GPU | CUDA |
The
.tar.zstfiles are internal runtime packages and are not required for normal installation.
Installation
macOS
- Download the correct
.dmgfile for your Mac - Open the DMG
- Drag StemDeck.app into the Applications folder
- Launch StemDeck
On first launch, StemDeck automatically downloads:
- Backend runtime
- FFmpeg
- Demucs model files
Approximate first-time download size: ~170 MB
Subsequent launches start in seconds.
Gatekeeper Warning (macOS)
Because the application is currently unsigned, macOS may display a security warning on first launch.
To open the app:
- Right click
StemDeck.app - Select Open
- Confirm by clicking Open again
Alternatively:
- Open System Settings → Privacy & Security
- Click Open Anyway
CI / Build Pipeline
- macOS arm64 and x64 packages were built and validated on a macOS Woodpecker CI agent before release upload.
- Windows packages were scanned with ClamAV during CI before publication.
v0.3.0-alpha.1
What's changed
Local MP3 and WAV file import
You can now process local audio files directly. Drag and drop an .mp3 or .wav file onto the import bar, or use the file picker — no YouTube URL required. The file goes through the same pipeline as a URL: stem separation, BPM and key analysis, LUFS measurement, and the full DAW player. Files up to 100 MB are accepted. Stem selection chips and all mixer and download features work identically.
URL and filename persist after app restart
When you load a track from the library, the original URL or filename now appears in the import bar. Previously this was lost on every Windows restart because the source address was stored only in session memory. It is now stored server-side and survives restarts. YouTube tracks show the full URL so you can change the stem selection and reprocess; local file tracks show the filename as a reference.
Fix release notes being overwritten with "System.Object[]"
The Windows release pipeline was reading the existing release body into a PowerShell variable. PowerShell captured the output as a String[] array, and converting it to a string produced the literal text System.Object[], replacing hand-written notes. Fixed by joining the array before string operations.
Artifact scan
Windows portable packages were scanned with ClamAV in CI before upload.
v0.2.0-alpha.7
What's changed
Store user data in %LocalAppData%\StemDeck (#25)
The Windows desktop app now keeps all mutable data (models, jobs, FFmpeg, logs) in %LocalAppData%\StemDeck instead of the install folder. This means your library and downloaded models survive across releases — no more copying a data/ folder when you unzip a new version.
On first launch after upgrading from alpha.6, existing data is automatically migrated via a same-volume move (instant, no copying).
Fix drag-and-drop to folders on Windows (#24)
Tracks could not be dragged to library folders in the Windows desktop app. Two issues were fixed:
dragDropEnabled: falseis now set intauri.conf.jsonso WebView2 no longer intercepts OS-level drag events at the Win32 layer, allowing HTML5dragover/dropto fire correctly.- The catalog rail panel background was not filling the full panel height in the collapsed state, causing
catalog-mainto wrap to an implicit grid row. Fixed with explicitgrid-template-rows: 1frand grid placement. dropOnFolderandgetDraggedTrackIdnow accept an explicittrackIdparameter and atext/plaindataTransfer fallback for cross-origin drag in WebView2.- Tracks can now be dragged from the trash back to the Library rail button.
Artifact scan
- Windows portable packages were scanned with ClamAV in CI before upload.
v0.2.0-alpha.6
What's changed
Fix drag-and-drop to folders on Windows (#23)
Tracks could not be dragged to library folders in the Windows desktop app. On WebView2, the dragover handler was gating e.preventDefault() behind a module-level dragId variable that can be null mid-drag — causing the browser to reject the drop. Fixed by checking e.dataTransfer.types for the custom MIME type instead, which is reliably populated during dragover on all browsers including WebView2.
Fix SSL errors when downloading model weights on macOS (#22)
Demucs failed with CERTIFICATE_VERIFY_FAILED on first run when using a Python.org install on macOS, which does not link to the system SSL store. Fixed by injecting SSL_CERT_FILE and REQUESTS_CA_BUNDLE pointing to certifi's CA bundle into the demucs subprocess environment before spawning it.
Artifact scan
- Windows portable packages were scanned with ClamAV in CI before upload.
v0.2.0-alpha.5
Summary
- Appbar collapses to a compact horizontal icon strip on double-click (same
grid-template-rowsanimation as widget sections); auto-collapses when a track finishes processing - Collapsed strip shows:
SDmonogram · URL icon · per-stem colored squares (active/inactive state) · Process button — all clickable - Clicking stem squares toggles selection; Process submits if URL is already set, otherwise expands; SD/URL icon always expands
- Brand subtitle shortened to "AI stem separation"
- Version label (
v0.1.0) added to brand area with optional green "New release available" chip that fetches the latest tag from the GitHub releases API on load - Fixed footer button underline and icon sizing
Artifact scan
- Windows portable packages were scanned with ClamAV in CI before upload.
v0.2.0-alpha.4
Summary
- Appbar collapses to a compact horizontal icon strip on double-click (same
grid-template-rowsanimation as widget sections); auto-collapses when a track finishes processing - Collapsed strip shows:
SDmonogram · URL icon · per-stem colored squares (active/inactive state) · Process button — all clickable - Clicking stem squares toggles selection; Process submits if URL is already set, otherwise expands; SD/URL icon always expands
- Brand subtitle shortened to "AI stem separation"
- Version label (
v0.1.0) added to brand area with optional green "New release available" chip that fetches the latest tag from the GitHub releases API on load - Fixed footer button underline and icon sizing
Artifact scan
- Windows portable packages were scanned with ClamAV in CI before upload.
v0.2.0-alpha.3
This release is a major UI overhaul — new DAW-style mixer, song catalog panel, collapsible appbar, and a large number of UX fixes across the player, transport, and import flow.
What's new
DAW-style mixer
The stem mixer has been completely redesigned. Each stem row now uses a horizontal DAW layout: waveform icon → stem name → fader → VU meter → dB value → Mute → Solo → Download.
- Fader renders as a styled range input with stem-colored fill and a circular thumb. Boost above 0 dB works — each stem routes through a Web Audio
GainNodeinstead ofHTMLAudioElement.volume, which is capped at 1.0 by the browser. - VU meter shows a real-time level bar driven by a pre-computed RMS envelope — no
AnalyserNodeorrequestAnimationFrameneeded. The bar fills left-to-right with a gradient that tips into red on loud passages. - Solo button lights up gold when active; soloing any stem silences the rest.
- Mute button turns red and stays fully visible when active (previously it faded out along with the dimmed row, making it hard to see the muted state).
- Download button opens the stem file in the system browser, including in the Tauri desktop app where native
<a download>was previously silently blocked.
Song catalog
A new catalog panel on the left sidebar shows the history of processed tracks.
- Tracks are listed with thumbnail, title, duration, and stem count.
- Click any entry to instantly reload that track into the player without re-processing.
- Tracks can be organised into colour-coded folders via drag-and-drop.
- A search bar filters by title.
- The panel collapses to a thumbnail strip to save space.
Collapsible appbar
The import bar at the top now collapses to a compact icon strip on double-click, using the same grid-template-rows: 0fr ↔ 1fr animation as the widget sections. It auto-collapses when a track finishes processing so the waveform gets full vertical space.
The collapsed strip contains:
- SD monogram — expands the appbar
- URL icon — expands the appbar
- Per-stem coloured squares — show active/inactive state; click to toggle stem selection without expanding
- Process button — submits the job if a URL or file is set; otherwise expands the appbar
Version badge and update chip
The brand area now shows the current version. If a newer release is available on GitHub, a green "New release available" chip appears next to the version and links to the releases page.
Transport improvements
AudioContext.resume()fires beforemultitrack.play()in the same gesture handler (Safari requires this to unblock autoplay).- Loop region and playhead state reset cleanly on new track load; playhead snaps to loop start on play.
- Keyboard shortcut
Ltoggles loop;I/Oset loop in/out points at the current playhead position.
Import flow
- File drop onto the URL bar — drag an MP3 or WAV directly onto the input area. A pill shows the filename and size; a clear button removes it.
- Stem choice chips use Spotify-style filter semantics: first click on a chip while all are selected switches to "only this stem"; subsequent clicks add to the selection; deselecting the last chip wraps back to "all selected".
Diagnostics
- Global
window.errorandunhandledrejectionhandlers log to the console with file, line, and stack trace. - Per-stem
<audio>elements attach anerrorlistener that logs the MediaError code and message.
CI
- Fixed: all pipeline steps now carry
backend: kubernetes, ensuring they run on the k3s agent and not the local Windows agent on main-branch pushes and releases.
Setup (macOS / Linux)
Unchanged — ./run.sh setup && ./run.sh start.
Known limitations
Same as previous alphas. The Windows app is ALPHA — expect rough edges.