AaronDB
"Simplicity is not about making things easy. It is about untangling complexity." - Rich Hickey
AaronDB is a BEAM-native temporal Datalog engine written in Gleam. Its strongest current shape is a fact-oriented database core built around a transactor actor, immutable-style state transitions, in-memory indexes, and a custom query engine.
This repository also contains experimental distributed, search, MCP, and cognitive layers. Those subsystems are not all at the same maturity level. See docs/feature_maturity.md and docs/project_boundaries.md before adopting non-core features.
Core Model
- Facts, not objects: data is represented as datoms.
- Actor-owned writes: a transactor process serializes state transitions.
- Query over values: reads execute against database state snapshots.
- Storage is pluggable: the engine is decoupled from persistence adapters.
What Is Solid Today
- In-memory transactional core
- Datom model with transaction and valid-time fields
- Query DSL and interpreted query execution
- Pull, history, diff, and speculative state evaluation
- Constraints for uniqueness, cardinality, predicates, and composites
- Broad automated test coverage
Maturity Snapshot
| Area | Status | Notes |
|---|---|---|
Core DB API (aarondb) | Stable | Primary strength of the repository |
| Query DSL and pull APIs | Stable | Backed by passing tests |
| Temporal querying and diff | Stable/Beta | Usable, but still tied to large core modules |
| Graph, vector, BM25, federation | Beta | Implemented, but less bounded than core |
| Sharding and distributed queries | Beta/Experimental | Works as scatter/gather; not a full distributed query fabric |
| Raft and HA claims | Inactive stub | Pure leader-election state machine exists but is not wired into the engine (election-only; no log replication). Retained as a documented stub. See src/aarondb/raft.gleam |
| MCP server and agent tooling | Experimental | Partial tool coverage and explicit TODOs remain |
Installation
Add aarondb to your gleam.toml:
[dependencies]
aarondb = "3.0.0"
Why 3.0.0 Is Better
AaronDB 3.0.0 is a breaking cleanup release that removes experimental surface and dead weight.
- Removed the GleamCMS layer — the experimental mist/wisp/lustre HTTP/CMS product surface that was mixed into the DB repo. It was fully self-contained and never imported by the core, tests, or the MCP layer.
- Pruned 9 now-unused dependencies — mist, wisp, lustre, gleam_http, simplifile, gleam_regexp, gleam_crypto, logging (direct deps 13→4; manifest packages 25→5).
- Bumped
gleam_stdlibto 1.0 (zero breakage in this codebase). - Demoted raft to a documented stub — the vestigial leader-election state machine is unwired from the engine and the inert public
is_leaderAPI is removed. - CI and release workflows target the current Gleam toolchain on OTP 27.
- The package remains green: 169 tests pass with zero warnings.
Basic Usage
Create an in-memory database:
import aarondb
let db = aarondb.new()
Transact facts:
import aarondb
import aarondb/fact.{EntityId, Str, Uid}
let assert Ok(_state) = aarondb.transact(db, [
#(Uid(EntityId(101)), "user/name", Str("Alice")),
#(Uid(EntityId(101)), "user/role", Str("Admin")),
])
Query with the DSL:
import aarondb
import aarondb/q
let query =
q.select(["name"])
|> q.where(q.v("e"), "user/role", q.s("Admin"))
|> q.where(q.v("e"), "user/name", q.v("name"))
|> q.to_clauses()
let results = aarondb.query(db, query)
Use temporal and pull APIs:
import aarondb
import aarondb/fact
let history = aarondb.history(db, fact.Uid(fact.EntityId(101)))
let entity = aarondb.pull(db, fact.Uid(fact.EntityId(101)), aarondb.pull_all())
Start a sharded cluster when you explicitly want the experimental distributed layer:
import aarondb/sharded
let assert Ok(cluster) = sharded.start_sharded("cluster", 4, None)
Documentation
Current Recommendation
Treat AaronDB first as a temporal Datalog engine with a strong in-memory core. Adopt peripheral layers only with explicit evaluation of their maturity and operational trade-offs.