# obj
> The embedded document database. Dependable. Portable. Zero-infrastructure.
`obj` is to document storage what SQLite is to relational storage — a
self-contained, serverless, single-file database with a stable file
format, full ACID semantics, broad platform support, and a track record
of not breaking things. It is written in Rust and designed to last.
**Status.** v1.0 — stable on-disk format, stable C ABI (`libobj`),
stable Python ABI (`obj-py`).
---
## Quickstart
```toml
# Cargo.toml
[dependencies]
obj = "1.0"
serde = { version = "1", features = ["derive"] }
```
```rust
use obj::Db;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, obj::Document)]
struct Order {
customer_id: u64,
total_cents: u64,
}
fn main() -> obj::Result<()> {
let dir = tempfile::tempdir()?;
let db = Db::open(dir.path().join("app.obj"))?;
let id = db.insert(Order { customer_id: 1, total_cents: 4_200 })?;
let back: Option<Order> = db.get::<Order>(id)?;
assert_eq!(back.unwrap().total_cents, 4_200);
Ok(())
}
```
The collection name and schema version default to the type name and
`1`; override either with `#[obj(collection = "...", version = N)]`.
See the crate docs for the full API (queries, indexes, transactions,
migrations).
---
## Bindings
**CLI (`obj` binary).** A read-only inspector and operator tool:
`obj dump`, `obj check`, `obj stat`, `obj backup`. Built from the
[`obj-cli`](./crates/obj-cli) crate.
**C ABI (`libobj`).** A `cdylib` + `staticlib` with a cbindgen-
generated `libobj.h`. The C ABI is stable within a major version; an
application linking `libobj` need not be recompiled across `obj`
patch / minor releases. Built from the [`libobj`](./crates/libobj)
crate.
**Python (`obj-py`).** A PyO3 + `abi3-py39` extension wheel. Same
typed API exposed as Python classes. Built from the
[`obj-py`](./crates/obj-py) crate.
---
## Performance
Headline numbers on Linux x86-64, NVMe SSD, release build, medians
over 1 000 runs against ~512-byte documents:
| Point read, warm cache | ~150 ns | Zero-copy through pager cache |
| Indexed lookup (`find_unique`) | ~200 ns | B+tree traversal |
| Single insert (implicit transaction) | ~650 ns | WAL append + group commit |
| Batch insert, 1 000 docs / one txn | ~900 µs | |
| Collection scan, 100 000 docs | ~38 ms | Sequential leaf walk |
| Concurrent readers, 8 threads | linear | No reader contention |
The reproducible bench harness and full table live in
[`docs/performance.md`](./docs/performance.md).
---
## Documentation
- [`docs/format.md`](./docs/format.md) — the on-disk format
specification. v1.0-frozen.
- [`docs/concurrency.md`](./docs/concurrency.md) — the
reader-snapshot / writer-lock / busy-timeout protocol.
- [`docs/performance.md`](./docs/performance.md) — the bench harness
and reproducible numbers.
- [`docs/unsafe-audit.md`](./docs/unsafe-audit.md) — every `unsafe`
block and its `// SAFETY:` rationale.
- [`design.md`](./design.md) — the elevator pitch and design
constraints.
---
## Contributing
See [`CONTRIBUTING.md`](./CONTRIBUTING.md) for the rule set this
project enforces — the power-of-ten discipline, the `#[allow]`
justification policy, the multi-agent orchestration workflow, and the
release process.
---
## License
`obj` is dual-licensed under either of
- [MIT License](./LICENSE-MIT)
- [Apache License, Version 2.0](./LICENSE-APACHE)
at your option. The `.obj` file-format specification in
[`docs/format.md`](./docs/format.md) is released into the public
domain — any implementation may read and write `.obj` files without
restriction.