How we rewrote SQLite in five languages without hand-writing a line of code

One neutral specification, five generated database engines and a WebAssembly build, all checked against SQLite’s own test corpus. Here is how it worked, and what it does and doesn’t prove.

Leaf
One specification in, five engines and a WebAssembly build out.

We wanted to know whether a serious, production-grade system could be rebuilt without engineers writing application code by hand. So we picked one of the most widely deployed databases in the world and tried.

What we built

We wrote a single, language-neutral specification of SQLite and used it to generate complete database engines in five languages (C, Rust, Zig, Go and Python), plus a WebAssembly build. No one on the team wrote engine code by hand: people wrote and refined the specification, and agents produced the implementations.

The project at a glance
Language targets5 + WebAssembly
Specification~36,000 lines
Generated engine code~208,000 lines
Including test and benchmark harnesses~249,000 lines
Lines of code per line of spec~5.8×

Why SQLite

SQLite made a demanding but fair test case for three reasons:

  • Its behaviour is precisely defined. Decades of use have pinned down how it should respond to almost any query, so there is a clear standard to match.
  • It has a public, independent test suite. SQLite’s sqllogictest corpus gives an objective measure of correctness that we didn’t write ourselves.
  • It is genuinely complex. Parsing, query planning, storage and transactions all have to work together. If the approach works here, it isn’t limited to toy problems.

The specification

The specification is the real product of this project. It describes what the engine must do (SQL syntax and semantics, query execution, the on-disk file format, transactions and error behaviour) without saying how any particular language should implement it.

Keeping it language-neutral was the point. A specification that leans on one language’s idioms produces one good implementation and four awkward ones.

The process

1. Write the specification

Engineers wrote and reviewed the specification section by section, treating it like code: versioned, reviewed and tested for ambiguity.

2. Generate the implementations

Agents generated each engine from the same specification. When an implementation was wrong, we fixed the specification and regenerated, rather than patching the generated code.

3. Validate against sqllogictest

Every engine ran against SQLite’s upstream sqllogictest corpus, 622 test files in all, and was scored against the results of mainline SQLite.

4. Verify byte identity

Passing tests isn’t the same as being compatible. We also compared the database files each engine wrote against files written by mainline SQLite, byte for byte.

Results

sqllogictest results across 622 files
EngineCoverage of mainline resultsCrashes
Mainline SQLite (reference)100.00%—
C, Rust, Zig, Go99.93–99.96%0
Python98.94%0

On byte identity, all five engines produced database files with SHA-1 hashes identical to mainline SQLite on both test fixtures.

When an engine was wrong, we fixed the specification, not the code.

What we learned

The specification is where the engineering happens

Most of the senior engineering time went into making the specification precise. Every ambiguity we left in showed up later as a divergence between engines.

An independent test suite defines “done”

Because we didn’t write the tests, nobody could argue about what correct meant. That kept the project honest.

Byte-level checks catch what tests miss

Comparing output files exposed differences that query results alone never would.

Generated code still needs engineering judgement

Correctness came from the process. Performance didn’t, and that is where people still matter most.

What we’re not claiming

  • The generated engines are not faster than SQLite. They lost INSERT throughput in every comparison we ran.
  • This is not a drop-in replacement for SQLite in production.
  • The test results describe compatibility with SQLite’s test corpus, not every behaviour a real application might rely on.

Why this matters

For decades, rewriting a large system meant years of work and enormous risk. This project suggests a different model: invest in a precise specification and an independent way to verify it, and the implementation becomes far cheaper to produce, and to produce again.

That is the same approach we bring to client platforms through refactoring, migrations and full rewrites. If you have a system that is overdue for one, we’d like to hear about it.

Explore the projectSource code, specification and test results
View repository [link]
TagsSQLiteSpecification-driven developmentAI agentsRewritesDatabases

Bring us
the hard part.

Complex platforms, overdue rewrites, agentic workflows. That’s the work we enjoy most.

Contact Us