Add a schema-free embedded database to a Scala app using ordinary case classes.
Query past states of your data or compare two snapshots using its built-in time travel.
Run typed Datalog-style queries with joins, aggregations, and recursive rules over in-memory data.
| mattlianje/datomlite | starlake-ai/quack-on-demand | janikdotzel/akka-http-quickstart-scala | |
|---|---|---|---|
| Stars | 16 | 13 | — |
| Language | Scala | Scala | Scala |
| Last pushed | — | — | 2023-05-19 |
| Maintenance | — | — | Dormant |
| Setup difficulty | easy | moderate | easy |
| Complexity | 3/5 | 4/5 | 2/5 |
| Audience | developer | ops devops | developer |
Figures from each repo's GitHub metadata at analysis time.
Datomlite is a small embedded database written in Scala 3, meant to be dropped straight into another Scala program rather than run as a separate server. It has no dependencies outside of Scala itself and works on the JVM, in JavaScript through Scala.js, and as a native binary. The author describes it as a database as a value, meaning the database is an in-memory object that you create, write to, and read from like any other Scala value, no setup file or schema definition step required. The schema is whatever ordinary case classes you define. You derive a marker called Entity on each case class, and that case class becomes the shape of records in the database. Behind the scenes, each record is split into entry-attribute-value triples and written to an append-only log, then rebuilt back into typed Scala objects when you read. Because the log only grows, every past state of the database stays around, which lets you ask what the data looked like at an earlier point or compare two snapshots. Reads are done with a typed query API that looks like normal Scala collections. You can call db.where to list rows, filter them, count them, take the first match, or run for-comprehensions over multiple entity types to do joins. There is also a Datalog-style query block, plus support for projections, aggregations, sorting and paging, named-tuple results, window functions, recursive rules, anti-joins, and a pull form that lets you shape the output, including following references in reverse. Writes go through transactions that commit atomically, so either every assert and retract in a block succeeds or none do. Multiple threads can transact at the same time, conflicts are resolved by a compare-and-swap retry loop, so there is no single-writer lock. Reads always operate on an immutable snapshot taken at the start of the call, which makes the read code easy to reason about. Storage can be plugged in by implementing a Storage interface, so the live in-memory projection can be backed by whatever persistence layer fits the host application. The README also lists time travel, change listeners, predicates that lower to index probes, and debug pretty-printing of state and log. The full README is longer than what was shown.
An embedded, dependency-free Scala database that lives inside your program as an in-memory value, with typed queries, full history, and safe concurrent writes.
Mainly Scala. The stack also includes Scala 3, Scala.js, JVM.
Setup difficulty is rated easy, with roughly 30min to a first successful run.
Mainly developer.
This repo across BitVibe Labs
Verify against the repo before relying on details.