Skip to main content

Install and run the runtime

Apollia publishes no package on crates.io or PyPI yet, so you build it from a checkout. This guide is for developers. It takes you from a clone to a running daemon that can execute an agent, and then to the Tauri desktop app in dev mode, on macOS, Linux, or Windows. Plan for one longer first build (Rust compiles the workspace once), then rebuilds are incremental.

If you only want to run the finished desktop application, download a prebuilt installer instead: Install the desktop app.

Every command runs from the repository root unless stated otherwise.

Prerequisites​

The build needs a Rust toolchain, Python, and Git on every platform. The desktop app adds Node.js, the cargo tauri CLI, and a per-OS webview toolchain. Install the shared tools first, then the OS-specific section for your machine.

Shared (all platforms)​

  • Rust toolchain (stable). Install it from rustup.rs if you do not have cargo. The repository pins an exact compiler in rust-toolchain.toml; rustup reads that pin and installs the matching toolchain automatically the first time you build inside the checkout, so you do not select a version by hand.

  • Python 3.13, available as python3. The runtime embeds Python to run the tools and workflows of packages, and the SDK installs into it. The checkout declares the exact version in .python-version.

  • Git. Required to clone the repository.

  • For the desktop app only: Node.js 20 or newer (the project builds the UI on Node 22) with npm, and the cargo tauri CLI:

    cargo install tauri-cli --version "^2"
  • For local inference: the daemon serves local GGUF models through an embedded llama-server. A packaged build bundles it; on a source build you need llama-server on your PATH (see the last section), no compiler required. Building the optional speech-to-text runner from source additionally needs CMake and a C/C++ compiler.

macOS​

  • Xcode Command Line Tools, for the C/C++ toolchain and the WebKit webview the desktop app renders into:

    xcode-select --install
  • PyO3 must find the right interpreter at build time. If the default python3 is not the one you want, point it explicitly before building. With Homebrew Python:

    export PYO3_PYTHON=$(brew --prefix [email protected])/bin/python3.13
  • Building the optional speech-to-text runner from source needs CMake (brew install cmake); the compiler comes from the Command Line Tools above.

  • The desktop app requires macOS 13 (Ventura) or newer.

Linux (Debian / Ubuntu)​

Install the build toolchain plus the Tauri v2 webview and system libraries. On Debian and Ubuntu:

sudo apt-get update
sudo apt-get install -y \
build-essential pkg-config libssl-dev \
libgtk-3-dev libwebkit2gtk-4.1-dev \
libayatana-appindicator3-dev librsvg2-dev \
libsoup-3.0-dev libjavascriptcoregtk-4.1-dev \
libasound2-dev libpulse-dev libjack-jackd2-dev \
python3-dev clang cmake file

What each group is for:

  • build-essential pkg-config libssl-dev: C/C++ toolchain and linking.
  • libgtk-3-dev libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev libsoup-3.0-dev libjavascriptcoregtk-4.1-dev: the Tauri v2 webview and tray dependencies. Needed only for the desktop app.
  • libasound2-dev libpulse-dev libjack-jackd2-dev: audio headers for the desktop app's speech-to-text capture. Needed only for the desktop app.
  • python3-dev: headers for the embedded Python.
  • clang cmake: needed only if you build the speech-to-text runner from source.

If you are building only the command-line runtime and not the desktop app, you can skip the webview and audio groups and install just build-essential pkg-config libssl-dev python3-dev (plus clang cmake for the speech-to-text runner).

On other distributions install the equivalents of the same libraries. Package names differ (for example WebKitGTK 4.1, GTK 3, libayatana-appindicator, and librsvg development packages); verify the exact names for your distribution against the Tauri v2 prerequisites.

Windows​

  • Microsoft C++ Build Tools (the "Desktop development with C++" workload from the Visual Studio Build Tools installer), for the MSVC compiler and linker.

  • Microsoft Edge WebView2 runtime. It is preinstalled on current Windows 11 and updated Windows 10. If it is missing, install the "Evergreen Bootstrapper" from Microsoft's WebView2 Runtime download page. Needed only for the desktop app.

  • CMake, only if you build the speech-to-text runner from source.

  • LLVM (provides libclang.dll for bindgen), only if you build the speech-to-text runner from source. Install with winget install LLVM.LLVM, then point bindgen at it before building:

    $env:LIBCLANG_PATH = "C:\Program Files\LLVM\bin"

    Without LIBCLANG_PATH, the whisper-rs-sys build fails with Unable to find libclang.

  • Run the commands below from a shell where cargo, python, git, and (for the desktop app) npm are on PATH. The runtime primitives are tested on macOS and Linux; on Windows, verify the daemon commands on your machine and prefer a developer PowerShell that has the MSVC environment loaded.

Step 1: clone and build the daemon​

git clone https://github.com/Apollia-OS/apollia-os.git
cd apollia-os
cargo build -p apollia-cli

Build the apollia-cli crate specifically. A workspace-wide build (cargo build --workspace) also pulls in the desktop crate, which requires the full webview toolchain from the platform sections above; scope the build to apollia-cli to compile just the runtime.

The crate is named apollia-cli but the binary it produces is apollia-os, at target/debug/apollia-os. That naming is deliberate; do not look for a file called apollia-cli. Put the binary on your PATH so the rest of this guide can call it by name:

export PATH="$PWD/target/debug:$PATH"

On Windows the binary is target\debug\apollia-os.exe; add target\debug to your PATH the equivalent way.

This build talks to OpenAI-compatible servers, Ollama among them, and serves local GGUF models through the embedded llama-server. On a source build that engine has to be on your PATH, covered in the last section.

Step 2: install the SDK​

An agent is a record declared in the apollia.toml of a package; the Python a package brings is its tools and its workflows, written with the SDK. Install the apollia package in editable mode into the same interpreter the runtime uses.

Create a virtual environment first. Homebrew, Debian and Fedora ship Python as an externally managed environment (PEP 668): installing into it directly stops with error: externally-managed-environment, and the runtime runs the Python of packages with the interpreter it finds on PATH, so the environment you activate here is the one it will use.

python3 -m venv .venv
source .venv/bin/activate
pip install -e ./sdk

On Windows, activate with .venv\Scripts\activate instead.

Keep this environment activated in every terminal where you run apollia-os. If you prefer a system-wide install and accept the consequences, pip install --break-system-packages -e ./sdk is the escape hatch, not the recommended path.

Step 3: configure a model backend​

An agent that generates text needs a backend. Pick one path.

llm setup --local writes straight to the local database and works offline. Every other llm subcommand, including backends create, reload and status, talks to the daemon. If you take the server path, or want to check with llm status, start the daemon first with step 4 and come back here.

Server: register an OpenAI-compatible server (a self-hosted vLLM or LM Studio, or a LiteLLM gateway) with its address and, when it requires one, an API key. That is the only way such a server authenticates; there is no OAuth flow for one.

apollia-os llm backends create prod --provider openai \
--base-url http://10.0.0.5:8000/v1 --model qwen3-32b \
--api-key "$VLLM_API_KEY" --default

A key given as is moves to the secret store before the backend is saved, and the backend database keeps only the fact that the store holds it. --api-key also accepts a ${VAR} form, which names an environment variable resolved at startup instead.

Use the model id your server serves for --model; the value above is only an example.

Local: point the runtime at a .gguf file on your machine. This registers the backend; the daemon serves it through the embedded llama-server (see the last section for the llama-server requirement).

apollia-os llm setup --local --model /path/to/model.gguf

Either way, reload the backend registry and confirm the backend is visible. A freshly configured backend does not appear in llm status until you reload:

apollia-os llm reload
apollia-os llm status

Step 4: start the daemon​

apollia-os start --port 7771

On its first run the runtime creates its data directory at ~/.apollia. It listens on a Unix socket (~/.apollia/runtime.sock by default, set to 0600 after binding) and on 127.0.0.1:7771. apollia-os start always binds TCP; --port chooses the number, and omitting it takes [api].port of apollia.toml (7771 by default) rather than leaving the port closed. On first boot it writes an API token to ~/.apollia/api-token; TCP callers must present it as a bearer credential, while the Unix socket is local-trust and needs none. Leave this terminal running and open a second one for the next steps.

On Windows there is no Unix socket. The runtime serves a named pipe instead, \\.\pipe\apollia-runtime-<user>, and the command line opens it without you naming anything. TCP is bound there too, and the pipe is not local-trust: it carries the same bearer token as TCP, because a pipe takes a default security descriptor rather than the socket's 0600.

Step 5: run an agent​

An agent ships in a package. Write the starting package, build it and install it:

apollia-os package new hello
apollia-os package build hello
apollia-os package install hello-0.1.0.apo

The starting package brings one agent and one Python tool. Then send the agent a task:

apollia-os run hello "hello from Apollia"

The agent answers with the model backend configured in step 3: an agent is a mission the model carries out, so run needs one.

You should see its answer. To write your own agent from scratch, follow Your first agent.

Step 6: stop the daemon​

apollia-os stop

Run the desktop app in dev mode​

The Tauri desktop app is the graphical front end over the same runtime. To bring it up from source, install the frontend dependencies once, then start the dev build. This needs Node.js, the cargo tauri CLI, and the per-OS webview prerequisites from the sections above.

Install the Svelte UI dependencies (a just recipe wraps npm ci):

just desktop-ui-install
# equivalent to: cd crates/apollia-desktop/ui && npm ci

Start the app in dev mode. This launches the Vite dev server for the UI and the Tauri shell with hot reload:

just desktop-dev
# equivalent to: cd crates/apollia-desktop && cargo tauri dev

The first cargo tauri dev compiles the desktop crate and can take a while; subsequent runs are incremental. The window uses the system webview (WebKit on macOS and Linux, WebView2 on Windows), so make sure your platform's webview prerequisites are installed.

For local inference inside the dev app, make sure llama-server is on your PATH (next section); the daemon the app embeds serves local GGUF models through it. See Get the most from local inference.

Build a release desktop bundle​

The just recipes below produce a distributable desktop installer (.dmg on macOS, .deb/.AppImage on Linux, .msi/.exe on Windows). They run bundle-cli.sh, which stages the Python runtime, the apollia-os CLI, the speech-to-text runners, and a pinned llama-server binary.

Each recipe accepts two optional arguments:

ArgumentRoleDefault (macOS / Linux / Windows)
targetRust triple passed to cargo tauri buildaarch64-apple-darwin / x86_64-unknown-linux-gnu / x86_64-pc-windows-msvc
runnersSpace-separated list of runner backends to build and bundlecpu metal / cpu / cpu

The runners value controls two things:

  1. Which apollia-runner-{backend} sidecars are compiled and copied into the bundle.
  2. Which prebuilt llama-server asset is downloaded. The script picks the first GPU backend in the list (metal, cuda, rocm, or vulkan); if none is present it falls back to CPU. Setting APOLLIA_DESKTOP_LLAMA_BACKEND overrides that choice and the list is not consulted, which is how the just recipes and the release pipeline bundle a Vulkan engine on Windows and Linux whatever the speech-to-text runners.

cpu is always included as a universal fallback. Add one GPU backend that matches your hardware:

HardwareTypical runners valueNotes
Apple Siliconcpu metalDefault macOS preset
NVIDIA (CUDA 12+)cpu cudaBuilds the CUDA speech-to-text runner. The bundled LLM engine stays Vulkan: no bundle carries a CUDA llama-server, on any platform, and asking for one (APOLLIA_DESKTOP_LLAMA_BACKEND=cuda) stops the script on could not bundle llama-server (cuda). The installed application downloads the CUDA engine on demand from the engine channel; to bundle a build of your own, pass LLAMA_SERVER_DIR
AMD Radeon / Intel Arccpu vulkanLLM and STT on GPU through Vulkan; the STT runner needs the Vulkan SDK (VULKAN_SDK) at build time
AMD Pro / Instinct + HIP SDKcpu rocmLLM and STT on ROCm where supported

Platform presets:

# macOS Apple Silicon, Metal + CPU fallback (defaults)
just release-macos

# Linux x86_64, CPU only (default)
just release-linux

# Windows x86_64, CPU only (default)
just release-windows

Each preset takes the runner set as its one argument:

# Windows with Vulkan LLM (AMD / Intel / fallback NVIDIA)
just release-windows "cpu vulkan"

# Windows with the CUDA speech-to-text runner (NVIDIA); the engine stays Vulkan
just release-windows "cpu cuda"

# Linux with Vulkan
just release-linux "cpu vulkan"

# macOS with a custom runner set
just release-macos "cpu metal"

For a triple and runner set not covered by a preset, use the generic recipe:

just release-desktop x86_64-pc-windows-msvc "cpu vulkan"
just release-desktop x86_64-unknown-linux-gnu "cpu rocm"
just release-desktop aarch64-apple-darwin "cpu metal"

The bundled llama-server engine is fetched from the pinned upstream llama.cpp release, which publishes builds for macOS (arm64 and x86-64), Linux x86-64 (CPU, Vulkan, ROCm), Linux arm64 (CPU) and Windows x86-64 (CPU, Vulkan). For any other couple, build llama.cpp yourself and pass LLAMA_SERVER_DIR=<bin dir>; the recipe then bundles your build. The CUDA engine is never bundled: it is published on the engine channel and downloaded by the installed application.

On Windows, export LIBCLANG_PATH in the same shell before running any of these recipes (see the Windows prerequisites above). On Linux, the speech-to-text runner additionally needs clang and cmake in your package manager.

The bundle lands under target/<triple>/release/bundle/ (for example target/x86_64-pc-windows-msvc/release/bundle/msi/ on Windows).

Local GGUF inference​

Local models run through an embedded llama-server (upstream llama.cpp) that the daemon spawns and supervises over its OpenAI-compatible HTTP API, with native tool calling (--jinja) and continuous batching. The provider name stays llama-cpp.

A packaged desktop build stages llama-server automatically, next to the speech-to-text runners, so nothing is needed there. On a source build the daemon looks for llama-server on your PATH. Provide one of:

an upstream install that puts llama-server on your PATH, for example brew install llama.cpp on macOS or a llama.cpp build on Linux.

The repository also has a just llama-server recipe. It does not satisfy this prerequisite: it expects llama-server to be on the PATH already, and it starts a separate server on port 8899 that the daemon does not talk to. It is a developer bench for comparing against a hand-tuned server, not an install step.

If a local backend is configured but no llama-server is reachable, LLM calls fail with a 503 Service Unavailable and a BackendUnavailable reason; put the engine on your PATH to resolve it.

There is no download command for models. Obtain a .gguf file yourself (for example from a model hub) and place it in ~/.apollia/models/, then point a local backend at it with apollia-os llm setup --local --model <path.gguf>. The model subcommands list and delete the files already present (list, delete), query the Hugging Face registry (search, show), report the hardware and rank the models this machine should run (hardware, recommend), and choose the embeddings model (embeddings); see the CLI reference.

Speech-to-text is a separate, optional component. The apollia-runner sidecar, built with a local-* feature (local-metal, local-cpu, local-cuda, local-rocm, local-vulkan), runs whisper out of process; it no longer serves LLM inference. A packaged build bundles it, and from source you build it only if you want local dictation.

Next steps​

  • Write and run your own agent: Your first agent.
  • Start the runtime at logon, without a terminal and without administrator rights: apollia-os service install (then service status, and service uninstall to remove it), on macOS, Linux and Windows.
  • Run Apollia as a managed service: Deploy in production.
  • Every flag on every command is in the CLI reference.