Skip to content

Building

Tobias Vorwachs edited this page Oct 29, 2026 · 4 revisions

Building from source

Prerequisites

  • Rust, stable toolchain 1.90 or newer (via rustup), with the rustfmt and clippy components.
  • Node.js 24 (the version CI uses) and npm.
  • No protoc is needed: the protobuf compiler is vendored (protoc-bin-vendored).

Linux, Debian/Ubuntu (24.04 in CI)

sudo apt-get install -y --no-install-recommends \
  libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev \
  libxdo-dev libasound2-dev cmake patchelf xdg-utils build-essential pkg-config libssl-dev

Linux, Arch/CachyOS

sudo pacman -S --needed base-devel webkit2gtk-4.1 libayatana-appindicator librsvg \
  xdotool alsa-lib cmake openssl pkgconf patchelf xdg-utils

Windows

Visual Studio Build Tools with the "Desktop development with C++" workload (MSVC), and the WebView2 runtime (preinstalled on Windows 11).

macOS

Xcode command line tools: xcode-select --install.

Get the code and run

git clone https://github.com/Mumcord/mumcord.git mumcord && cd mumcord
npm ci
npm run tauri dev

npm run tauri dev starts the Vite dev server (port 1420) and the Tauri app with the Rust engine.

Build release packages

npm run tauri build

Bundles land in target/release/bundle/:

OS Output
Linux appimage/*.AppImage
Windows nsis/*-setup.exe
macOS dmg/*.dmg and macos/*.app

Each OS builds only its own formats. To build a single format pass -- --bundles appimage (or nsis, dmg), for example npm run tauri build -- --bundles appimage. Release builds are signed and notarized on macOS; the others are unsigned. The version shown in the app comes from git at build time: dev~YYYYMMDD for a local build (plus -dirty with uncommitted changes), dev~<short commit> for CI builds and the plain version for a release tag. Set MUMCORD_VERSION to override it.

A quick build without bundling, as used in CI: npm run tauri build -- --debug --no-bundle.

npm run build type-checks and builds the frontend only (tsc -b && vite build).

TypeScript bindings (tauri-specta)

The UI calls the engine through generated TypeScript bindings in ui/src/bindings/commands.ts. Never edit that file by hand. It is regenerated by debug runs of the app and by cargo test -p mumcord. Set the environment variable MUMCORD_SKIP_BINDINGS_EXPORT=1 to stop a run from rewriting the tracked file (the E2E setup does this). After you change a Tauri command, run the app in debug mode or the tests and commit the regenerated file. See docs/engine-api.md for the contract.

Versions

Nobody bumps the version in the manifests by hand. A release tag vX.Y.Z sets X.Y.Z in the app, the diagnostics file, the log and the update check; CI builds of main or a pull request say dev~<short commit>; local builds say dev~YYYYMMDD, plus -dirty when the tree has uncommitted changes. Dev builds do not look for updates. Installer formats need a plain number, so dev bundles carry the version of the latest v* tag. Details are in RELEASING.md.

Third-party notices and SBOM

CI generates the third-party notices: each release regenerates them from the tagged commit before bundling, and after dependency changes on main a workflow opens a pull request with the updated files. Generating them fails when a dependency uses a licence that is not on the allowlist (about.toml for Rust crates, the script for npm packages); the tools are pinned in scripts/license-tools.env. Every release also ships a software bill of materials (CycloneDX) per package type, listed in SHA256SUMS, and its files get a GitHub build provenance attestation. To run the notices locally use scripts/generate-notices.sh. It needs cargo-about (cargo install cargo-about --locked --features cli) and an installed node_modules. It writes THIRD_PARTY_NOTICES and ui/public/third-party-notices.txt.

Publishing the library crates

The library crates mumcord-protocol, mumcord-codec, mumcord-store, mumcord-audio and mumcord-p2p are published on crates.io with the app version (the first three libraries from 0.4.2 on; store and p2p from 0.4.3 on). Audio depends on codec and p2p on protocol, so those two wait for them.

  • The Release workflow does it in its last job, after the draft release exists. Tags with a pre-release suffix (such as -rc.1) are skipped, and a version that is already on crates.io is skipped per crate.
  • To publish the current main without a release, run the Publish crates workflow (.github/workflows/publish-crates.yml) from the Actions tab. It needs the repository secret CARGO_REGISTRY_TOKEN.
  • On a minor or major version bump also change the version of the mumcord-codec, mumcord-protocol and mumcord-store entries in the workspace Cargo.toml (the minor series, for example 0.4), or publishing audio and p2p fails.
  • Check a crate locally with cargo publish -p <crate> --dry-run --locked. Each crate must stay self-contained: only crates.io dependencies and no files outside its own directory.

Details are in RELEASING.md in the repository.

Clone this wiki locally