layer · Parser
reads .zanith files at app start
lex · parse · validate — Chevrotain-backed, single pass
- · lexer · token stream
- · parser · CST → AST
- · validator · invariants
Zanith · v0.1.0 · runtime-first
A SQL data engine that doesn't generate code. The schema parses once at startup into a runtime graph; queries compile to parameterized SQL on the way to the wire.
schematic · zanith engine · v0.1.0 · drawn in code, no images
Zanith treats the schema as data the engine reads at startup — not as a build target the engine compiles toward. The schema graph is the only artifact. Queries are typed, compiled, and executed against it without ever materializing a single generated file.
03 — Anatomy
Every layer ships in the same package. None of them runs at build time. Click into /how-it-works for the deep dive.
layer · Parser
lex · parse · validate — Chevrotain-backed, single pass
layer · Graph
models · fields · relations · indexes — sub-ms lookups, 3.4MB at scale
layer · Compiler
expression tree · join planner · parameter binding — never interpolation
layer · Adapter
shipped: pg · postgres.js · planned: mysql · sqlite
04 — The compile step
Three steps. Build an expression tree from the args, plan against the graph, emit SQL. Parameters are bound by the driver — never spliced into the SQL string.
db.user.findMany({ where: { email: { contains: '@example.com' }, role: { in: ['ADMIN', 'EDITOR'] }, }, orderBy: { createdAt: 'desc' }, take: 10,});SELECT id, email, role, created_atFROM usersWHERE email ILIKE $1 AND role IN ($2, $3)ORDER BY created_at DESCLIMIT 10;05 — At scale
Engine overhead, not end-to-end query time. Sourced from the engine's benchmark suite, re-run on every commit. The full table with comparison anchors lives on /proof.
M01 · measured
1,000 models lex, parse, and validate into a runtime graph at app start. Once. Ten thousand iterations measured.
src · engine/test/benchmark/scale.test.ts
M02 · measured
Indexed lookups against the in-memory graph. Sub-microsecond per call, well below human-perceptible latency.
src · engine/test/benchmark/scale.test.ts
M03 · measured
A typical SELECT with a WHERE clause compiles to parameterized SQL. Per query. The compiler isn't on your hot path.
src · engine/test/benchmark/execution.test.ts
M04 · measured
1,000 models in memory. The size of one user-uploaded photo. A 500-model generated client commonly runs ten times that on disk.
src · engine/test/benchmark/scale.test.ts
Disclosed honestly: the test suite reports 191 of 192 passing — one flaky benchmark assertion, a ratio against a near-zero baseline. The figure above (2.4µs) is from the per-op assertion, which is stable.
06 — The day-to-day
No generate command. No regenerated client to commit. No watch process to fight. Twenty-five milliseconds, end-to-end.
Edit schema.zanith
model User { id Int @id @default(autoincrement()) email String @unique+ phone String? @unique name String?}App reparse
New field live
await db.user.findMany({ where: { phone: { startsWith: '+1' } },});// → SELECT id, email, phone FROM users// WHERE phone LIKE $107 — Where this is heading
What follows isn't a roadmap; it's a thesis. When the schema is data the engine reads — not code the engine compiles — these are the surfaces that become natural to build. Some are planned. Some are horizon. Two are speculative. None of them are promises.
Schema diff that understands intent, not just structure.
Today the engine knows the runtime graph; tomorrow it knows how to evolve it. Compare two .zanith files, surface what changed, generate the SQL — with a human review step and a rollback path baked in.
before
after
The single biggest gap between the current engine and a production-team replacement for Prisma. We won't ship Zanith for real apps without it.
An in-browser visual editor for the runtime graph.
Drag models onto a canvas. Wire relations. Watch the .zanith file update in real time. Watch the SQL diff. Let the graph tell you what it'll generate before you commit. The engine already exposes the graph as data; Studio is the surface that makes that data manipulable.
When the schema is data, the editor is just another consumer. The runtime-first architecture earns this for free.
Same compiler. Different SQL dialect emit step.
PostgreSQL today. MySQL/MariaDB and SQLite next. Edge runtimes (Cloudflare D1, Neon serverless) on the horizon. The architecture is database-agnostic; only the adapter set is single.
Engines that wake up cold and stay light.
An 88KB bundle that compiles a query in 2.4µs is the right shape for the edge. A graph that holds 1,000 models in 3.4MB is the right shape for cold-start. We're not there yet — but the architecture is.
Browser code gets the same types as server code.
Ask, with full schema context.
Ask the graph what was true last quarter.
Every schema change is a commit; every commit is a graph. Querying a historical graph means querying the data as it was, not as it is. We don't know exactly how this looks yet — but it sits naturally in a runtime-first world.
planned—has prerequisites in the codebase, target version namedhorizon—direction we'd build toward, no firm date yetspeculative—worth thinking about, careful about claiming
08 — Engineered by Fybyte
Schema-as-runtime is harder to engineer and harder to make fast. We did it because the easy architecture was already built ten times over — and it stops being easy at exactly the scale we needed the engine to work.
Zanith ships from Fybyte's stack. Same engine, same tests, same compiler running in production as on this page. The rigor isn't a marketing claim; it's a constraint we live with daily.
Fybyte
An engineering company building the operating layer for modern operations. Zanith is the data engine; we use it for everything we ship.
Products shipped
Engineering posture
open · sourced · cited
Working at
production scale, indie cadence.
The runtime is 88.97KB. The graph holds 1,000 models in 3.4MB. Every byte was chosen, not accumulated. The engine is small enough to read in an afternoon — that's a design constraint, not a coincidence.
192 tests run on every commit. Every figure on this site is sourced to a file you can grep. We disclose 191 of 192 passing and explain the one rather than rounding to all-green.
Comparisons to Prisma, Drizzle, and TypeORM will cite published benchmarks. Until those numbers are sourced, the marketing copy hedges with one consistent phrase. We won't manufacture credibility.
Zanith isn't a sandbox project. It's the data layer Fybyte uses in production — the same engine that handles real workloads, written by the same team that runs them.
The data layer hasn't moved in a decade. We're moving it — by rewriting the architecture, not by tweaking the codegen.
The roadmap moved. A web UI, a migrations system with risk scoring, and a recovery layer that lets a destructive op be walked back. Each is a real surface — not a checkbox.
Bundled with the engine. Eight tabs. Two levels — workspace and database.
Generate, plan, verify, apply. CI passes the score it's willing to absorb.
Soft-drop or archive every destructive op. Restorable until you cleanup.
$ zanith studio --allow-sqlstudio listening on http://127.0.0.1:4321Why code generation is the wrong shape — eight chapters
The strongest argument for runtime-first, in eight chapters with the canonical numbers and the architectural diagrams.
Four layers, end to end · the engine made visible
Side-by-side examples with the compiled output
Sourced benchmark numbers, honest disclosures
The build log — engine map + release tracks
Built by Fybyte · v0.1.0 · MIT licensed when the package publishes · the build log is on /roadmap.