Tauri + Leptos SSR
May 29, 2026 · View on GitHub
A cargo-generate template for building Tauri v2 desktop apps with full Leptos server-side rendering.
The Axum SSR server runs as a Tokio task inside the Tauri process on a dynamically allocated port. The WebView navigates to the embedded server, giving you true SSR with server functions while shipping a single native binary.
Features
- Full SSR — Leptos renders pages server-side within the Tauri process
- Server Functions —
#[server]functions execute in the same process - Single Binary — no sidecar, no companion process
- Dynamic Port — binds to
127.0.0.1:0to avoid port conflicts - Tailwind CSS 4 — via
@import "tailwindcss"instyle/input.css - Dual-Target — the
appcrate supports both Tauri (filesystem) and Spin (KV store) via feature flags
Prerequisites
- Rust (stable)
- cargo-generate:
cargo install --locked cargo-generate - cargo-leptos:
cargo install --locked cargo-leptos - Tauri CLI:
cargo install tauri-cli
Getting Started
Generate from Template
cargo generate --git git@github.com:codeitlikemiley/tauri-leptos-ssr
Development
cargo tauri dev
This runs cargo leptos watch (via beforeDevCommand) which starts the standalone server binary on :3000 with hot-reload. Tauri opens the WebView at http://localhost:3000.
Production Build
cargo tauri build
This runs cargo leptos build --release (via beforeBuildCommand), bundles the site assets as Tauri resources, and compiles everything into a single native binary with the Axum server embedded.
Project Structure
├── app/ # Shared Leptos app (components, routes, server functions)
│ └── src/lib.rs # App component, server fns, build_router()
├── frontend/ # WASM client entry point (hydration)
├── server/ # Standalone Axum server (dev mode only)
├── src-tauri/ # Tauri desktop shell
│ ├── src/lib.rs # Embedded Axum server setup + lifecycle
│ └── tauri.conf.json
├── style/ # Tailwind CSS input
├── public/ # Static assets (favicon, etc.)
└── Cargo.toml # Workspace config + cargo-leptos metadata
How It Works
Dev Mode (cargo tauri dev)
beforeDevCommandrunscargo leptos watch→ starts theserverbinary on:3000- Tauri WebView loads
http://localhost:3000 - File changes trigger hot-reload via cargo-leptos
Release Mode (cargo tauri build)
beforeBuildCommandrunscargo leptos build --release- Produces
target/site/with WASM, CSS, and static assets - Tauri bundles
target/site/+Cargo.tomlas resources - At runtime,
src-tauri/src/lib.rs:- Reads Leptos config from the bundled
Cargo.toml - Spawns Axum as a Tokio task on
127.0.0.1:0(OS-assigned port) - Waits for the server to become ready
- Navigates the WebView to
http://127.0.0.1:{port}
- Reads Leptos config from the bundled
- On window close, the server task is gracefully aborted
Feature Flags
| Crate | Feature | Purpose |
|---|---|---|
app | hydrate | Client-side hydration (WASM) |
app | ssr | Server-side rendering (native) |
app | spin | Spin KV storage backend |
Testing
Setup
cd end2end
npm install
npx playwright install
Run Tests
cargo leptos end-to-end
# Release mode
cargo leptos end-to-end --release
# View report
cd end2end && npx playwright show-report
For Tauri WebDriver testing, see the Tauri docs.
License
MIT