Meet unionid
unionid is a lightweight Rust database that makes algebraic data types (ADTs) part of the database schema. It runs as an embedded Rust engine, a local redb database, or a standalone TCP/HTTP service.
What it changes
Applications often represent state with a string and several nullable fields. A running task needs a worker and attempt; a completed task needs a result. Those rules usually exist only in application code.
unionid describes every legal shape in the schema:
enum State {
Pending
Running {
worker: text
attempt: int
}
Done {
result: text
}
Failed {
message: text
retryable: bool
}
}The database validates constructors, payloads, defaults, field paths, indexes, and migrations. Queries understand the same types and exhaustively match variants instead of treating ADTs as untyped JSON.
Three ways to run it
| Entry point | Best for | Storage |
|---|---|---|
Engine::memory() | tests and temporary work | process memory |
Engine::open_redb / unionid run --db | desktop tools and embedded apps | redb file |
unionid server + TCP/HTTP adapter | multiprocess clients and controlled services | redb file |
All three share the parser, type checker, executor, and transaction semantics. Learn with the CLI, then move to Rust or a network boundary without rewriting schemas and queries.
Current boundaries
- One machine, one database owner, serialized writes;
ConcurrentEnginesupports up to eight consistent read snapshots. - Around 10,000 rows is the comfortable range. 100,000 rows is a tested upper bound, not a routine target.
- ADTs, indexes, aggregation, stable pagination, and bounded lookup are supported; general flattened joins, windows, and distributed execution are not.
- Users, roles, row permissions, subscriptions, CDC, and application caching remain application responsibilities.
Suggested path
- Complete Getting started.
- Learn the generated project layout.
- Model data with types and values.
- Learn queries and mutations.
- Choose the CLI, Rust API, or network protocol.
- Read Operations before production.