Desktop app with the Local Stack (Tauri + sidecar api)

The desktop-app template with the api INSIDE the app — a Tauri sidecar built by voltro build api --target executable, SQLite in the app-data directory, the window talking to 127.0.0.1. No server, works offline.

The desktop app plus the Local Stack: your api ships inside the app as a Tauri sidecar, packaged by voltro build api --target executable, with SQLite in the app-data directory. The window talks to 127.0.0.1; there is no server to run. Template id: desktop-local-app (kind: desktop).

Boots on macOS, Windows and Linux with its api inside. The framework's desktop proof workflow scaffolds this template, builds the api's executable, places it as the sidecar with its bundle, compiles the Tauri shell on all three runners and starts it: the window's boot report says the adapter was installed, the web app mounted and the sidecar answered at its url (green on 2026-09-26). Signing, notarization and your own updater key remain your steps.

Scaffold

voltro create-project acme --api=api-backend --web=frontend-app --desktop=desktop-local-app

What differs from desktop-app

desktop-local-app/
  voltro.desktop.ts          # + localStack: { api: '@acme/api', binary: 'desktop-api' }
  src/
    main.ts                  # starts the sidecar with startLocalStack, hands the url to the web app
    lib/localStack.ts        # PURE: the shell adapter over @tauri-apps/plugin-shell's Command — tested
  src-tauri/
    tauri.conf.json          # bundle.externalBin + bundle.resources for the sidecar and its bundle
    Cargo.toml, src/lib.rs   # + tauri-plugin-shell
  tests/localStack.test.ts
  • voltro desktop capabilities scopes shell:allow-execute / shell:allow-spawn to the one sidecar; no blanket shell permission.
  • voltro desktop build builds the api, runs the executable target, and places src-tauri/binaries/desktop-api-<host triple> plus src-tauri/resources/serveBundle/ before tauri build.
  • src/main.ts is the window's platform script (voltro desktop platform, injected before the web app's scripts): it installs the adapter, starts the sidecar, reads its port from the first serve log line (never guessed), waits for /internal/readiness, and writes the url into the pairing record the web app reads — one place for "which api", shared with LAN dev pairing. Its boot report to window_booted carries the sidecar's url.

What the api needs beside the binary

The sidecar runs serve . with its own .env: mint VOLTRO_SESSION_SECRET per installation and keep it in the keychain command pair rather than a file. A local database means @voltro/sql-sqlite, whose native leaf (better-sqlite3) resolves at runtime from node_modules beside the binary — ship it as the api's node_modules, as voltro serve would. Sync to a cloud api is the local-first mixin on the tables you declare; the shell decides nothing about it.