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:0 to avoid port conflicts
  • Tailwind CSS 4 — via @import "tailwindcss" in style/input.css
  • Dual-Target — the app crate supports both Tauri (filesystem) and Spin (KV store) via feature flags

Prerequisites

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)

  1. beforeDevCommand runs cargo leptos watch → starts the server binary on :3000
  2. Tauri WebView loads http://localhost:3000
  3. File changes trigger hot-reload via cargo-leptos

Release Mode (cargo tauri build)

  1. beforeBuildCommand runs cargo leptos build --release
  2. Produces target/site/ with WASM, CSS, and static assets
  3. Tauri bundles target/site/ + Cargo.toml as resources
  4. 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}
  5. On window close, the server task is gracefully aborted

Feature Flags

CrateFeaturePurpose
apphydrateClient-side hydration (WASM)
appssrServer-side rendering (native)
appspinSpin 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