Native desktop app for the Delta Chat protocol. Tauri 2 shell wraps a Rust
daemon (server/) that bridges deltachat-jsonrpc to a Svelte 5 SPA
(frontend/) over a loopback WebSocket. Builds to a single ~15 MB binary
per OS (no Electron).
server/ # Rust crate `qxp-web` — axum + yerpc + deltachat-jsonrpc.
# Compiles to a library (used by the Tauri shell) AND
# a standalone binary (`cargo run` for headless dev).
frontend/ # Svelte 5 + Vite + TypeScript SPA.
src-tauri/ # Tauri 2 shell crate (`qxp-desktop`).
# Spawns the daemon in-process; opens a native window.
The repo is a flake. Run the app without installing anything:
nix run github:qxpchat/qxpInstall it into your profile:
nix profile add github:qxpchat/qxpOr declaratively — add the flake as an input and pull the package into your system or user config:
# flake.nix
inputs.qxp.url = "github:qxpchat/qxp";
# NixOS — configuration.nix (inputs threaded through via specialArgs)
environment.systemPackages = [ inputs.qxp.packages.${pkgs.system}.default ];
# …or home-manager
home.packages = [ inputs.qxp.packages.${pkgs.system}.default ];packages.default and apps.default are exposed for x86_64-linux and
aarch64-linux. The install also drops a desktop entry and icons, so qxp
shows up in your application launcher. The binary is wrapped with
WEBKIT_DISABLE_DMABUF_RENDERER=1, so it renders correctly on NixOS out
of the box.
Other distros: build from source — see below.
NixOS shell already wires the GTK / WebKit deps Tauri needs on Linux:
nix-shellTauri CLI (one-time, inside the shell):
cargo install tauri-cli --version "^2"cargo tauri devcargo tauri dev does three things in one command:
- Spawns a Vite dev server at
http://localhost:4040(hot reload). - Compiles the Tauri Rust shell (which spawns the daemon thread on
127.0.0.1:4041). - Opens a native window pointing at Vite. The frontend's WebSocket connects to the daemon at the loopback port.
First compile takes ~10 minutes (deltachat-core); subsequent rebuilds are sub-minute.
cargo tauri buildOutputs platform-native bundles under src-tauri/target/release/bundle/:
- Linux:
.AppImage,.deb - macOS:
.dmg(unsigned by default — see notes on macOS distribution) - Windows:
.msi/.exe
The frontend is built once via npm run build (configured as
beforeBuildCommand in tauri.conf.json) and Tauri serves the resulting
frontend/dist/ from tauri://localhost inside the bundle. The daemon
listens on 127.0.0.1:4041 exactly as in dev; the frontend detects the
Tauri context and connects there explicitly.
If you just want to iterate on the Svelte UI in a regular browser without booting Tauri:
make server # cargo run --release-ish; daemon at 127.0.0.1:4041
make ui # vite, 0.0.0.0:4040make ui proxies /ws, /upload, /file to the daemon. Browser at
http://localhost:4040.
Tauri places accounts under the per-OS app-data dir:
| OS | Path |
|---|---|
| Linux | ~/.local/share/chat.qxp.desktop/accounts |
| macOS | ~/Library/Application Support/chat.qxp.desktop/accounts |
| Windows | %APPDATA%\chat.qxp.desktop\accounts |
Standalone make server defaults to ./qxp-web-accounts/ relative to
server/ (override with --accounts-dir).
The unsigned bundle works locally but Gatekeeper blocks it on first launch for users (Settings → Privacy & Security → Open Anyway). For friction-free distribution use Homebrew Cask (cask formulas auto-strip the quarantine xattr) or pay for an Apple Developer Program account ($99 + KYC) and signed/notarize the build. Auto-update via Tauri's updater plugin requires a Developer ID signature.