Skip to content

Repository files navigation

Umari 🌊

Discord Book Sponsor Crates.io Version docs.rs Crates.io Total Downloads Crates.io License GitHub Contributors

Umari is a WASM-native event sourcing runtime. You write your business logic as ordinary Rust or TypeScript modules (commands, projectors, and effects), compile them to WebAssembly, and Umari takes care of event persistence, querying, module lifecycle, and replay.

There are no aggregates and no per-entity streams. Consistency is enforced through Dynamic Consistency Boundaries (DCB): each command declares exactly which events it cares about, and the runtime forms a boundary on the fly. Consistency comes from the query rather than from a grouping you committed to up front, which keeps the resulting systems easier to model and change as requirements shift.

Features

  • WASM-native modules: business logic runs as hot-reloadable, sandboxed WebAssembly components, isolated from the runtime and from each other.
  • No aggregates, no streams: DCB replaces per-aggregate streams with dynamic, query-driven consistency boundaries.
  • Three module types: commands (the only writers), projectors (SQLite read models), and effects (HTTP and third-party side effects).
  • Folds: derive state on demand by replaying only the events a command cares about. No snapshots or caches.
  • Fully replayable: drop every read model and replay from position 0 to rebuild state, without re-running side effects.
  • Built-in idempotency: per-command idempotency keys, plus a fold-check → side effect → record pattern for effects.
  • Crypto-shredding: per-scope AES-256-GCM encryption. Delete the key and those events become permanently unreadable.
  • Rust and TypeScript SDKs: both compile to the same WASM contract and interoperate over the same events.

Architecture

Module Reads Writes Role
Command Events (via folds) Events The only writers. Validate input, replay relevant events, emit new ones.
Projector Events Own SQLite DB Build read models. Deterministic and replayable from position 0.
Effect Events External world Call HTTP/APIs and trigger commands. Idempotent via fold-check → act → record.
External trigger (HTTP, webhook, cron)
    │
    ▼
Command ──► emits events ──► Event Store (UmaDB)
                                  │
                ┌─────────────────┴─────────────────┐
                ▼                                   ▼
           Projector                              Effect
           (builds read models                   (side effects:
            in SQLite)                            HTTP, calls commands)
                                                     │
                                                     ▼
                                                  Command
                                                  (private, for
                                                   idempotency)

Commands are the only writers; projectors and effects subscribe but never emit. An effect can call a command, which writes more events, which in turn trigger more projectors and effects. The event store is the single source of truth: read models are caches and side effects are derivable from the log. Drop the databases and replay from the start, and the system rebuilds itself.

Installation

Runtime

The server and CLI ship as prebuilt binaries for macOS and Linux (x86_64 and arm64):

# CLI: scaffold, build, and deploy modules
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/tqwewe/umari/releases/latest/download/umari-cli-installer.sh | sh

# Server: the runtime host
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/tqwewe/umari/releases/latest/download/umari-server-installer.sh | sh

The server requires a running UmaDB event store.

SDK

cargo add umari        # Rust (also run: rustup target add wasm32-wasip2)
npm install @umari/js  # TypeScript

Getting Started

umari init my-app                  # scaffold a Rust or TypeScript workspace
umari new command create-project   # add a command, projector, or effect
umari new projector projects
umari new effect notify-user
umari deploy                       # build and upload every module

See The Umari Book for concepts, patterns, and complete examples in both Rust and TypeScript.

Documentation

Repository Layout

Crate Description
umari Rust SDK: traits, types, derive macros, WASM guest library
umari-macros Derive macros: Event, EventSet, DomainIds, FromDomainIds, #[export_command]
umari-runtime Wasmtime-based module runner, event dispatch, actor system
umari-api HTTP API server (Axum): upload modules, execute commands, manage lifecycle
umari-server Server binary: runtime, API, and web UI
umari-cli CLI for scaffolding, building, and deploying modules
umari-ui Web UI built with HTMX

The TypeScript SDK (@umari/js) lives in packages/js.

Contributing

Contributions are welcome. Open an issue, improve the book in docs/src, or pick up existing work. To build the book locally, run cargo install mdbook mdbook-tabs, then mdbook serve docs (the tab theme assets are checked in under docs/theme/).

Support

If Umari is useful to you and you'd like to help fund continued development, please consider sponsoring on GitHub. It directly funds the time spent on the project.

License

Licensed under the Apache License, Version 2.0 (LICENSE or http://www.apache.org/licenses/LICENSE-2.0).

About

wasm-native event sourcing

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages