Apollo Download ManagerApollo Download Manager
On this page

Development setup

This page takes you from a fresh clone of the Apollo Download Manager repository to a running development window on Windows, Linux or macOS. If something fails, see TROUBLESHOOTING.md.

Quick start

After installing the prerequisites below:

pnpm check:prereqs            # checks Node.js, pnpm, Rust and the platform libraries; prints the fix for anything missing
pnpm install --frozen-lockfile
pnpm dev                      # builds the Rust shell and opens the app with hot reload

The first pnpm dev compiles every Rust dependency and takes several minutes (see Build times). Later runs reuse the build.

You should see a window titled Apollo Download Manager (dev). The first time, it asks where downloads should go. After that, it opens on the downloads, with the navigation and the status bar (UI_ARCHITECTURE.md):

The app on Windows, light theme

The same window in the dark theme:

The app on Windows, dark theme

To try the app without touching your own development data, point it at another folder: VELOCITY_V2_DATA_DIR=<folder> pnpm dev (COEXISTENCE.md).

The same build on Linux (Ubuntu 24.04 under WSL2/WSLg):

The development shell on Linux

Prerequisites

ToolVersionWhy
Node.js^22.13.0 || ^24.0.0 || >=26.0.0 (the engines field in package.json; set by Vitest and ESLint)Frontend tooling
pnpmexactly the version in package.json → packageManager (12.14.0)Package manager
Rustinstalled with rustup; rust-toolchain.toml pins the toolchain (1.99.1) and rustup installs it automaticallyDesktop shell and core
Platform librariessee belowTauri's webview and native build
vcpkga clone with the baseline commit in scripts/native/vcpkg/vcpkg.json, bootstrapped, in VCPKG_ROOT, C: cpkg or ~/vcpkgBuilds libtorrent, Boost and OpenSSL for the torrent bridge (BUILDING_NATIVE.md)

pnpm check:prereqs checks all of these. It only reads your system; it never installs or changes anything.

pnpm

Use one of the routes from the pnpm installation docs:

  • Corepack (bundled with the Node.js releases we support): run corepack enable once. Corepack then runs the exact pnpm version pinned in package.json.

  • npm: npx get-pnpm (needs Node.js 22.13 or newer). pnpm's docs recommend this route on Windows, because Windows Defender may block the standalone installer.

Note that pnpm setup and pnpm doctor are built-in pnpm commands, which is why the prerequisite check is named check:prereqs.

Windows 10/11

Requirements from the Tauri prerequisites:

  1. Microsoft C++ Build Tools with the Desktop development with C++ workload: https://visualstudio.microsoft.com/visual-cpp-build-tools/.

  2. WebView2 Runtime. It is preinstalled on Windows 10 (1803 and later) and Windows 11; otherwise install the Evergreen Bootstrapper from https://developer.microsoft.com/microsoft-edge/webview2/.

  3. Rust: winget install --id Rustlang.Rustup, and choose the MSVC toolchain (x86_64-pc-windows-msvc) as the default host. Open a new terminal afterwards.

  4. Node.js LTS from https://nodejs.org/, then pnpm as described above.

Linux (Debian/Ubuntu)

sudo apt update
sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

Then install Node.js and pnpm. Fedora and Arch package lists are in the Tauri prerequisites.

macOS

xcode-select --install
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

Then install Node.js and pnpm.

Everyday commands

CommandWhat it does
pnpm devRun the desktop app with hot reload (Vite on port 1430, Rust rebuilt on change)
pnpm dev:webRun only the web UI in a browser (native commands are unavailable there)
pnpm dev:engineBuild the transfer engine (velocity-transfer), the torrent helper (velocity-torrent, which needs libtorrent built: BUILDING_NATIVE.md) and the browser's native host (velocity-native-host-v2, #65) beside the app, where the app looks for them; pnpm dev runs it first (#58)
pnpm check:fastLevel L1 checks: cargo fmt --check, clippy with -D warnings, cargo test, tsc, ESLint (zero warnings), Vitest. It runs every check even after a failure and prints a summary
pnpm test:focused -- <area>Level L2: the tests of one crate, frontend or scripts while you iterate
pnpm check:prLevel L3 run locally: only the checks this branch's changes need
pnpm check:fullLevel L4 run locally: L1, then the production web build and the Rust release build
pnpm check:linksRelative links and heading anchors in every Markdown file
pnpm check:guidanceThe agent guidance files: sizes, rule globs, skill fields, pnpm commands, forbidden terms, repeats (AGENT_GUIDANCE.md)
pnpm test, pnpm test:watchFrontend and script unit tests (Vitest), once or in watch mode
pnpm rust:testRust unit tests
pnpm typecheck, pnpm lintTypeScript and ESLint on their own
pnpm native:buildBuild libcurl and the other native libraries from verified sources and write build-info.json, then build libtorrent, Boost and OpenSSL with vcpkg and write libtorrent-info.json. The first run takes about 2.5 min on Windows and 5 min on Linux for libcurl, plus 15 to 35 min for libtorrent; later runs reuse both in seconds. Every Rust build links them, so check:fast, check:pr and test:focused run it first (BUILDING_NATIVE.md)
pnpm native:verifyCheck that build-info.json and every built library still match the lock file; pnpm tauri build runs it first

Run pnpm check:fast before every pull request. TESTING.md describes each level, how check:pr picks checks, and the build settings that keep feedback fast.

Running beside the original Velocity Download Manager

The app is named Apollo Download Manager (ADR-0018), and runs beside V1, during development and after release:

V1Apollo DM development build
Product nameVelocity Download ManagerApollo Download Manager (dev)
Bundle identifiercom.velocity.downloadmanagerdev.velocity.downloadmanager.v2 (release builds will use com.velocity.downloadmanager.v2; ADR-0003)
Dev server port14201430

The bundle identifier, not the name, keeps the apps apart: it decides the data directory and the single-instance lock. Tests in velocity-core and src-tauri fail if Apollo Download Manager's identifier, data folder, pipe name, native host name or dev port ever matches V1's. The identity lives in branding.json; COEXISTENCE.md has the details. Apollo Download Manager keeps its own identity after release too (ADR-0003): the installer offers to remove V1 (#81), and importing V1 data is a separate decision (#24).

Build times

The two tables below were measured on 2026-10-21, before the #3 profile change (check timings has the current figures).

Windows 11 (build 26200), Intel Core i7-13620H (16 logical CPUs), 15.7 GiB RAM, NVMe SSD, Rust 1.99.1, Node.js 24.12.0, pnpm 12.14.0:

StepTime
First cargo build --workspace from an empty target/278 s
pnpm check:fast, first run (clippy compiles its own artefacts)128 s
pnpm check:fast, warm7 s
cargo build --workspace with no changes3 s
Rebuild after a one-line change in crates/velocity-core19 s
Rebuild after a one-line change in src-tauri17 s
Vite dev server start0.23 s

Linking the desktop executable dominates incremental rebuilds. Issue #3 tuned this (see check timings).

Linux: Ubuntu 24.04.4 LTS under WSL2 (kernel 6.6.87.2) on the same PC, limited to 2 vCPUs and 1.9 GiB RAM, with the same tool versions:

StepTime
First cargo build --workspace from an empty target/413 s
pnpm check:fast, first run191 s
pnpm check:fast, warm8 s
cargo build --workspace with no changes< 1 s
Rebuild after a one-line change in crates/velocity-core17 s
PlatformClean-clone run
Windows 11PASS (2026-10-21, machine above)
Linux (Ubuntu 24.04, WSL2/WSLg)PASS (2026-10-21). WSL is a real Linux kernel and userland, but not a native desktop install; WebKitGTK rendered through WSLg
macOSNOT RUN: no macOS machine was available

Check timings

Measured 2026-10-21 for #3 on the two machines above. Each figure is the median of node scripts/check-fast.mjs wall time after one warm-up run. "One-file change" means appending a comment line to crates/velocity-core/src/lib.rs before each run. That rebuilds the core and the desktop shell that depends on it.

pnpm check:fastBefore tuningAfter tuning
Windows, no-op9.2 s8.9 s
Windows, one-file change20.9 s14.0 s
Linux (WSL2, 2 vCPU, 1.9 GiB), no-op6.1 s5.5 s
Linux (WSL2, 2 vCPU, 1.9 GiB), one-file change66.7 s (18–123 s)7.0 s
  • Windows: 5 runs on each side, with the same scripts and only the Cargo.toml profile change reverted for "before". A first measurement on main's scripts, with 3 runs, gave 7.5 s and 25.8 s.

  • Linux: 3 runs before, on main, and 5 runs after.

  • Where the time goes: in a no-op run, mostly ESLint (about 4.5 s on Windows, 3 s on Linux). After a Rust change, mostly cargo test, which re-links the desktop shell. Before tuning, that link wrote a staticlib of about 660 MB on Linux; it is now about 140 MB. Under WSL's 1.9 GiB of memory, the link time varied a lot.

pnpm check:full on Windows: 249 s, of which the Rust release build took 232 s. Linux (WSL2): 224 s across the checks, of which the Rust release build took 215 s.

Repository layout

PathPurpose
src/React and TypeScript UI. It talks to Rust only through typed Tauri commands
src-tauri/Tauri 2 desktop shell. Commands stay thin and delegate to the core
crates/velocity-core/Core domain logic in Rust
crates/velocity-child/The child-process layer the engine and the torrent helper share
crates/velocity-lt/, crates/velocity-torrent/The torrent bridge over libtorrent, and the torrent engine with its helper program (TORRENTS.md)
scripts/Developer scripts (check:prereqs, the check:* and test:focused commands) and their tests
docs/Project documentation; README.md maps every document