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 image crate on desktop, browser APIs on web
  • Persistence: SQLite via varve-sync crate for document storage, localStorage/IndexedDB for settings
  • Print: Rust varve-print crate using lopdf for 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 types
  • varve-enginebuild_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 operations
  • varve-print — PDF generation with lopdf: path operators, font outlining, ICC profiles, crop marks, CMYK conversion
  • varve-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 TypeScript
  • varve-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:

  1. User interaction triggers a tool or context action
  2. Document mutation — The action calls an immutable Document operation (e.g., addNode, setProperty) producing a new Document
  3. State update — The new Document is set via setState, triggering a React re-render
  4. IR generation — CanvasArea walks the document tree, computes world transforms, and calls buildIr() to produce a flat array of RenderItems
  5. ReplayreplayIr(canvas, ir) draws each RenderItem using Canvas2D calls
  6. 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_ir Tauri command), available on desktop
  • 'wasm' — Calls WASM-compiled Rust engine, available in browser via varve_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 → RenderItems
  • hit_test — World point → node hit detection
  • sync_save / sync_load — SQLite document persistence
  • save_file_bytes — Binary file export
  • export_node_pdf — PDF generation with options
  • export_pdfx1a / export_pdfx4 — Print-ready PDF export
  • outline_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.