An application-database generator. Write one schema; get a tailored database.
forgedb.dev · Getting Started · Docs · Benchmarks
What it is
ForgeDB compiles a declarative .forge schema — at compile time — into a tailored
Rust database, a REST API (with an OpenAPI 3.1 spec), and typed clients for TypeScript,
Python, Rust, and Go. It is a code generator, not an ORM or query engine: your schema
is a compile-time input to generation, never a runtime input to a generic engine. The
generated code is specialized per schema over columnar storage, so there is no
generic-runtime layer to pay for — nothing reflects your schema at runtime.
Everything in this repository is open source under MIT OR Apache-2.0. See
docs/OPEN_CORE.md for the open-core boundary.
Status: early development (0.2.x, pre-1.0), not yet production-ready. What v1 actually guarantees — and what it defers — is stated plainly in
docs/WHAT_V1_IS.md. Trust that over any headline here.
One schema in, a stack out
User {
id: +uuid // auto-generated primary key
email: ^&string @pattern("^[^@]+@[^@]+\\.[a-z]{2,}$") // unique, indexed, format-checked
username: ^&string // unique, indexed
created_at: ^timestamp // indexed (ordered → range queries)
posts: [Post] // one-to-many
@index(created_at, username) // composite index
}
Post {
id: +uuid
title: ^string @length(5, 200) // indexed; length-validated
author: *User // required foreign key
view_count: ^u64 // indexed (ordered → range queries)
created_at: ^timestamp
tags: [Tag] // many-to-many
@index(author, created_at) // composite index
}
Tag {
id: +uuid
name: ^&string
posts: [Post] // many-to-many (bidirectional)
}
forgedb generate turns that into typed, schema-tailored methods — index probes,
not scans, and no runtime engine to interpret the schema (these are the real
generated signatures; probes return plain values, not a Result):
let ada = db.user.get_by_email; // Option<User> — O(1) unique lookup
let popular = db.post.find_by_view_count_range;
let recent = db.post.find_by_author_and_created_at; // Vec<Post> — composite index
db.link_post_tag; // many-to-many link
— plus a REST endpoint per model with filter/sort/pagination, the OpenAPI spec, and matching typed clients for TypeScript, Python, Rust, and Go (same methods, same shapes, no hand-written HTTP and no drift between them).
How it works
schema.forge
│ parser (lexer → AST) → validation
▼
codegen
├─→ Rust database code (columnar storage, typed query API, durable writes)
├─→ REST API (axum) (CRUD, relation traversal, query params)
├─→ OpenAPI 3.1 spec
├─→ typed REST clients (TypeScript, Python, Rust, Go — one per language)
├─→ in-process bindings (PyO3, NAPI-RS — embed the DB instead of calling it, opt-in)
├─→ browser read-replica (WASM, opt-in — the same generated engine, in a Worker)
└─→ migration transformer (offline, per-version data rewrite)
The storage is a columnar hybrid: fixed-size types (u64, f64, uuid, …) live in
packed columns for tight, cache-friendly access; variable-length data (strings, json)
rides an append-only column with an offset index. Because the generated code is monomorphized
to your exact schema, there is no dynamic dispatch over a generic row type. Performance is
measured, not asserted, and benchmarked fairly — with durability semantics matched
across engines. At the fsync-barrier tier ForgeDB ties SQLite and redb; relaxed, it's the
fastest of the group, with the smallest on-disk footprint of the embedded four. The
methodology and current numbers live in docs/BENCHMARKS.md.
What's real today
Implemented and working:
- Schema parser (lexer → AST) + validation; the
forgedbCLI - Columnar storage engine, WAL, in-process compaction
- Crash-safe durable writes; MVCC transactions + multi-process write coordination
- Codegen: Rust database, REST API (+ OpenAPI 3.1), typed REST clients for TypeScript / Python / Rust / Go
- Secondary + composite indexes, relation traversal, snapshot reads, live queries, backup/restore
- Multi-tenancy (verify-only JWT), schema migrations, browser read-replica (WASM)
- LSP server + VS Code extension; in-process native bindings (PyO3 for Python, NAPI-RS for Node / Bun)
Not built (and not near-term): generated UI components. The schema can reference UI components as contract markers, but ForgeDB does not generate component code today.
For the full, honest scope see docs/WHAT_V1_IS.md and
docs/V1_ROADMAP.md.
Why generate instead of run an engine
- One source of truth. The schema defines storage layout, the Rust database, the TS types, and the API — they cannot drift, because they are all generated from it.
- Compile-time, not runtime. Errors surface at build time; the compiler optimizes for your schema rather than a generic one.
- No runtime engine to interpret your schema. Generated code links only schema-agnostic substrate crates (storage, WAL, types); there is no ORM reflecting over a schema at runtime.
- Columnar from the start. Not a row store with columns bolted on.
Good fit: type-safe full-stack apps with stable schemas, local-first apps (browser read-replica), embedded use where the schema is known at compile time, services that want strong contracts. Poor fit: schemas that change shape at runtime, or ad-hoc analytics over unknown schemas.
Getting started
Install the CLI (macOS / Linux — Windows via WSL2), then scaffold a project:
|
# edit schema.forge, then:
The same binary is on every major channel — Homebrew, npm, pip/uv, Docker, Nix, and
cargo install forgedb. See docs/INSTALL.md for every path.
Or generate from a schema in a cloned checkout:
&&
See docs/GETTING_STARTED.md for the full loop with verified
output, docs/INSTALL.md for every install path, and
examples/ for worked schemas across many domains.
Documentation
The full docs — with an ecosystem toggle for TypeScript / Python / Rust / Go — are hosted at forgedb.dev/docs. The Markdown sources below are the same content.
Start here
- Getting Started — install → scaffold → generate → build → serve
- Schema Language Reference — the complete, parser-verified
.forgereference - What v1 Is — and Isn't — honest guarantees and limits
- Installing — every install path + the substrate version matrix
Operating
- Deployment — containers, env config, ops routes, multi-tenancy, JWT
- Migrations — how schema changes affect data at rest
- Versioning & Stability — the compatibility policy across surfaces
- Benchmarks — measured performance + methodology
Internals & contributing
- Architecture — system design and design decisions
- Public Crates — the schema-agnostic substrate crates
- Contributing · Development · Publishing
Contributing
Contributions are welcome — bug fixes, tests, docs, examples, and performance work
especially. Start with the Contributing Guide. Design proposals
are filed as rfc-labeled issues, not
committed docs.
- Issues: https://github.com/hoodiecollin/forgedb/issues
- Discussions: https://github.com/hoodiecollin/forgedb/discussions
License
Dual-licensed under MIT or Apache 2.0 at your option.