Skip to content

Tauri Stack

Tauri 2 + React + TypeScript + Tailwind + shadcn/ui + Zustand. Rust backend hosting a system webview.

What Tauri is

Tauri is a Rust framework for building desktop apps with web-based UIs. Unlike Electron (which bundles Chromium, ~250 MB overhead), Tauri uses the system’s native webview (WebView2 on Windows, WKWebView on macOS, WebKitGTK on Linux). This gives:

  • ~80–100 MB total app size vs Electron’s 250+ MB
  • Better memory usage (no second browser running)
  • Native OS look-and-feel for window chrome
  • Rust backend is a first-class citizen, not a glued-on subprocess

How Tauri talks to React

Two mechanisms:

Tauri commands (UI → Rust)

JavaScript calls Rust functions like normal async APIs:

import { invoke } from "@tauri-apps/api/core";
const patches = await invoke<Patch[]>("load_song", { songId: "abc" });

On the Rust side:

#[tauri::command]
async fn load_song(song_id: String) -> Result<Vec<Patch>, String> {
// ... business logic ...
}

Tauri auto-generates the IPC bridge. Round-trip time: sub-microsecond when in-process.

Tauri events (Rust → UI)

Rust pushes updates to the webview:

app_handle.emit("meter-update", MeterData { l: -3.0, r: -3.5 })?;
import { listen } from "@tauri-apps/api/event";
await listen<MeterData>("meter-update", (event) => {
setMeter(event.payload);
});

Used for real-time UI updates: meter levels, MIDI activity dots, patch-change notifications.

The full stack

LayerTechPurpose
Audio engineRust + OvertureReal-time audio processing, plugin hosting
App orchestrationRust + TauriShow/Song/Patch model, file I/O, command dispatch
IPCTauri commands + eventsUI ↔ Rust communication
UI runtimeSystem webview (WebView2 / WKWebView)Renders HTML/CSS/JS
UI frameworkReact 18 + TypeScriptComponent model
StylingTailwind CSS + shadcn/uiDesign system
StateZustandLightweight state management
BuildViteFast dev server, fast builds
Component devStorybook 8Isolated component development
TestingVitest + PlaywrightUnit + E2E

Why these specific choices

React over Vue/Svelte

  • Largest ecosystem
  • shadcn/ui is excellent and React-specific
  • Tauri Mobile docs / examples lean React
  • Hiring (if we ever hire) easiest

TypeScript not JavaScript

  • The data model (Show, Song, Patch, MIDI message, etc.) benefits enormously from typing
  • Tauri-generated bindings are typed

Tailwind + shadcn/ui

  • shadcn/ui = headless, customizable component primitives
  • Tailwind = utility-first CSS, fast iteration
  • Both work seamlessly with Storybook
  • Theme tokens (CSS variables) make light/dark/high-contrast trivial

Zustand over Redux / MobX

  • Tiny (~1KB)
  • No boilerplate
  • Works perfectly with React Hooks
  • Easy to reason about for a small-to-medium app

Vite over webpack

  • Faster dev server (sub-second HMR)
  • Better defaults
  • Tauri’s official template uses Vite

Process model

Tauri starts ONE main process (Rust). That process:

  1. Runs the Tauri runtime + main event loop
  2. Runs Stardust’s app code (Show/Song/Patch model, command handlers)
  3. Embeds Overture (audio library) — runs the audio thread inside this same process
  4. Spawns a system webview process for the UI (managed by Tauri)
  5. Spawns child processes per VST plugin for sandboxing

Total process count: 1 (Stardust) + 1 (webview, OS-managed) + N (plugins) = typically 5–15 processes for a real Show.

What about Electron

Comparison for the record:

Tauri 2Electron
Backend langRustNode.js
WebviewSystemBundled Chromium
Bundle size~10 MB installer, ~80 MB installed~50 MB installer, ~250 MB installed
MemoryLowerHigher (full Chromium instance)
AudioPure Rust (CPAL, etc.)Via Node native modules
Native APIsDirect Rustnode-ffi / native modules
Maturity2022+ stable2013+ mature

For an audio app, Rust + Tauri is the right call. Audio processing wants to be in a system language anyway.

What about Native (no webview)

We considered:

  • egui / iced — pure Rust UI frameworks
  • Native macOS Swift + Windows WPF — separate UIs per platform
  • Qt / GTK — cross-platform native toolkits

Verdict: webview gives us familiar UI tools (React) + faster iteration + good-enough performance. Native UI frameworks in Rust are not yet mature enough for an app this UI-heavy. Cross-platform native (Qt/GTK) carries its own legacy.

Performance

The webview runs UI rendering. Tauri commands are sub-microsecond. The audio thread is fully Rust, doesn’t go through the webview, doesn’t even know it exists.

So: UI runs at 30-60 FPS for animations, audio thread runs at 375 callbacks/sec (at 128 samples / 48 kHz), they coexist with no contention because they’re independent.