editsqlite runs in your tab · nothing uploads

Writing a database by hand

guide · 5 jul 2026

values 7, 'Ada',null, 3.5 record [hdr][types][bytes...] pages + tree header "SQLiteformat 3" then the judge: sqlite3 → PRAGMA integrity_check → "ok" two letters, earned the hard way reading a format is comprehension. writing it is confession.
the assembly line, and the judge waiting at the end.

Our reader parses SQLite files by hand, and building that parser felt like fluency. Then the editor needed the opposite direction — writing databases from scratch — and that fluency turned out to be reading-level only. A parser can shrug at things it doesn't understand; a writer's every byte is a claim the official engine will audit without mercy. That asymmetry is the whole story here.

The assembly line

Writing runs the read pipeline backwards. Each row's values are encoded into a record — serial types chosen frugally (a boolean costs zero bytes; the integer 300 costs two; text costs its length), with header varints in front. Records pack into 4KB leaf pages from the tail forward, a pointer array growing from the head, until a page is full and the next begins. If a table outgrows one leaf, an interior page is stacked above it, holding "rowids up to N live in page P" signposts. Finally page one is assembled — the schema table describing every other table, plus the 100-byte header with its magic string, page size, counts and the UTF-8 declaration. Every offset computed, nothing borrowed.

The bug that taught the lesson

First full test: the engine's integrity check returned a page of accusations — rowids out of order, a double reference to page one, an orphaned page. The cause was one line: pages are numbered from 1, arrays from 0, and our child pointers were recorded one page off from where the children actually lived. A parser with that bug misreads one file and you debug it; a writer with that bug builds a thousand confidently corrupt files. Which is why the certification bar is external: not "our tests pass" but the reference engine opens our output, walks 3,000 rows across 21 pages, answers aggregates correctly, and — the compliment we're proudest of — inserts its own rows into pages we laid out. When the engine starts building on your foundation, the design holds.