Architecture Overview
Varve is a local-first, cross-platform design suite with a native Rust engine powering the rendering pipeline. Desktop builds use Tauri 2, while the web version uses WebAssembly behind the same facade. This document describes the high-level architecture and data flow.
Philosophy: Local-First by Default
Varve is designed to work fully offline with no cloud dependency. Your designs never leave your machine unless you explicitly export them. This is a core architectural commitment:
- All computation happens locally (native Rust engine or WASM in the browser)
- Documents are saved as local files (.strata format)
- No telemetry, no cloud sync (optional collaboration is planned but opt-in)
- Full functionality with no internet connection
- Your data is yours — no lock-in, no subscription
Technology Stack
Varve uses a layered architecture with clear boundaries:
- Frontend: TypeScript + React 19, running in a Tauri 2 WebView (desktop) or directly in the browser (web)
- Backend Engine: Rust crate
varve-engine, compiled as native binary on desktop or as WASM for web - Desktop Shell: Tauri 2 with GTK/WebKitGTK on Linux, native frameworks on macOS/Windows
- Image Decoding: Rust via
imagecrate on desktop, browser APIs on web - Persistence: SQLite via
varve-synccrate for document storage, localStorage/IndexedDB for settings - Print: Rust
varve-printcrate usinglopdffor direct PDF generation
Monorepo Structure
The project is organized as a monorepo with two top-level directories:
Rust Crates (crates/)
varve-core— Geometry primitives (Point, Rect, Affine), Shape enum with hit-testing, SceneNode typesvarve-engine—build_render_ir()that converts a scene into a compact render IR (Intermediate Representation)varve-layout— Taffy-backed flex/grid layout engine (stub, pure-TS version active in editor)varve-sync— SQLite-based DocumentStore for save/load/list operationsvarve-print— PDF generation with lopdf: path operators, font outlining, ICC profiles, crop marks, CMYK conversionvarve-trace— Raster-to-vector auto-tracing: contour + centerline + pixel-art modes, Oklab quantization, Bézier fitting, hole pairing (native engine for Image Trace)varve-bridge— Shared IPC types for Tauri command serialization between Rust and TypeScriptvarve-wasm— WASM build target for in-browser engine execution
TypeScript Packages (packages/)
@varve/engine— Engine facade with createEngine(backend): stub/native/wasm. IR types, replayIr(canvas, ir), geometry helpers@varve/scene— Immutable Document model with add/insert/remove/move/rename/reparent ops, all node types@varve/editor— Full editor application: Shell, Canvas, Layers Panel, Inspector, tools, shortcuts, context@varve/ui— Design tokens (OKLCH color ramps, 3 themes, WCAG-AA), Icon system (typed Lucide), components (Button, Toolbar, NumberInput)@varve/shared— Shared utilities: affine math, viewport/camera, easing functions, text measurement, ordering (fractional-indexing)@varve/codegen— Code export: SVG, React/Tailwind, Flutter, SwiftUI, CSS Modules, animation formats@varve/prototype— Prototype engine: interactions, animation, transitions, runtime, navigation, variables@varve/import— Import parsers for SVG, PDF, PSD, AI, EPS, raster images@varve/platform— Platform abstraction interface (save/load/search files) with Tauri, web, and memory implementations
Data Flow
The editor follows a unidirectional data flow:
- User interaction triggers a tool or context action
- Document mutation — The action calls an immutable Document operation (e.g.,
addNode,setProperty) producing a new Document - State update — The new Document is set via
setState, triggering a React re-render - IR generation — CanvasArea walks the document tree, computes world transforms, and calls
buildIr()to produce a flat array of RenderItems - Replay —
replayIr(canvas, ir)draws each RenderItem using Canvas2D calls - Overlays — Selection handles, snap guides, ruler guides, grid, and other overlays render on top
Engine Facade
The engine facade (createEngine(backend)) abstracts the rendering backend:
'stub'— Pure TypeScript IR builder, runs in all environments, used for testing'native'— Calls Rust via Tauri IPC (build_render_irTauri command), available on desktop'wasm'— Calls WASM-compiled Rust engine, available in browser viavarve_wasm_bg.wasm
The facade includes withStubFallback — a one-shot circuit breaker that gracefully degrades to the stub engine if the native/WASM backend throws a deserialization error. This ensures a single malformed node never blanks the entire canvas.
IPC Bridge (Tauri)
On desktop, Tauri commands connect the TypeScript frontend to the Rust backend:
build_render_ir— Scene nodes → RenderItemshit_test— World point → node hit detectionsync_save/sync_load— SQLite document persistencesave_file_bytes— Binary file exportexport_node_pdf— PDF generation with optionsexport_pdfx1a/export_pdfx4— Print-ready PDF exportoutline_text— Text-to-path font outlining
The varve-bridge crate defines IpcSceneNode, IpcShape, and IpcRenderItem types with serde serialization for the JSON IPC channel.
Related Guides
See the Rendering Pipeline page for a deep dive into the rendering system.