Files
jellytau/docs/build/build-windows.md
T
dtourolle 2de91ae76c docs: move the root-level build docs under docs/build/
build-release.md, build-desktop-packages.md and build-windows.md sat at
the docs/ root while docker.md and build-builder-image.md were already in
docs/build/, so "where do build docs live" had two answers. They now have
one.

Referrers updated: README.md, docs-site/SUMMARY.md, and the ../ links
inside the moved files themselves, which each gained a level of depth —
Dockerfile, Dockerfile.arch, packaging/arch/PKGBUILD, CHANGELOG.md,
README.md, src-tauri/src/lib.rs and src/lib/services/webviewAudio.ts.
Every one of those was caught by check-doc-links.sh rather than by
reading, which is the point of having it.

Two referrers are left for their owners: CLAUDE.md line 173 and the
comment at scripts/build-windows-cross.sh line 11.
2026-08-20 19:32:04 +02:00

3.4 KiB

Windows build

JellyTau targets Linux and Android primarily, but a working Windows build — including an NSIS installer cross-compiled from Linux — is produced by the Docker tooling. It is not yet a first-class release target (no code signing / CI job / SMTC lockscreen), but it runs and plays media.

How playback works on Windows

  • Video — renders through the webview HTML5 <video> element (hls.js) on every platform; on Windows that is WebView2 (Chromium/Edge), which plays HLS + h264 fine. No Windows-specific code.
  • Audio-only (music) — the native audio backends are libmpv (Linux) and ExoPlayer (Android); neither exists on Windows. Instead create_player_backend() in ../src-tauri/src/lib.rs uses WebviewAudioBackend on non-Linux/non-Android targets: it hands the stream URL to a webview <audio> element (see ../src/lib/services/webviewAudio.ts), which reports state back through the same player_report_* round-trip the video path uses. Pure Rust + Tauri events.

Cross-compiling from Linux (MSVC + cargo-xwin)

We use the official Tauri cross-compile path: the MSVC target (x86_64-pc-windows-msvc) driven by cargo-xwin, which downloads the MSVC CRT / Windows SDK headers and links with lld. MSVC is the target Tauri officially supports for Windows (mingw/GNU is not), and — unlike GNU — it lets the Tauri CLI bundle the NSIS installer from a Linux host.

Why not mingw/GNU? The GNU target does link a valid .exe, but the Tauri CLI gates --bundles by the host OS unless it recognizes a real Windows build. --runner cargo-xwin --target x86_64-pc-windows-msvc is what flips it into Windows mode and enables the nsis/msi bundlers on Linux.

The builder image (../Dockerfile.builder) bakes in the whole toolchain: the x86_64-pc-windows-msvc rust target, cargo-xwin, lld, llvm, and nsis.

bun run docker:build:windows            # NSIS installer + .exe -> ./dist
WIN_BUNDLES=none bun run docker:build:windows   # exe only, skip bundling

Or directly on a host that has the toolchain:

scripts/build-windows-cross.sh                    # nsis installer + exe
WIN_BUNDLES=none scripts/build-windows-cross.sh   # exe only

Under the hood the build runs:

tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc --bundles nsis

Outputs:

  • .exesrc-tauri/target/x86_64-pc-windows-msvc/release/jellytau.exe
  • NSIS installer — .../release/bundle/nsis/*-setup.exe

(both copied to ./dist when OUTPUT_DIR is set).

Caveats

  • Cross-compilation is a last resort per Tauri's own docs — it's less tested than building on Windows. If it misbehaves, a windows-latest CI job or a Windows VM building natively (tauri build --bundles nsis) is the fallback.
  • Code signing is not wired up — the installer is unsigned, so Windows SmartScreen will warn on first run.

Outstanding for a first-class Windows release

  1. Gapless/crossfade + SMTC (lockscreen) — currently no-ops in the webview audio path.
  2. Downloaded (Local source) file playback needs convertFileSrc on the frontend; streaming works today.
  3. Code signing + a Windows packaging CI job.