graphitesql
A pure, safe, no_std-capable Rust re-implementation of SQLite, as a single
crate, aiming for byte-for-byte compatibility with the SQLite 3 database file
format.
Status: read + write working, with a broad SQL engine. graphitesql opens real SQLite files and creates databases that the real
sqlite3CLI opens withPRAGMA integrity_check = ok. Storage covers rowid andWITHOUT ROWIDtables, secondary/UNIQUE/partial/expression indexes, overflow pages,VACUUM, the fullauto_vacuumtrack, and the WAL read and write path. The SQL surface coversINNER/LEFT/RIGHT/FULL/NATURAL/USINGjoins, aggregates,GROUP BY/HAVING, compound queries, (recursive) CTEs, correlated subqueries &EXISTS, window functions, UPSERT,RETURNING,STRICTtables, generated columns, triggers, foreign keys, ATTACH / TEMP multi-schema, virtual tables (built-inseries,rtree, andfts5modules — full-textMATCHwith phrases, prefixes, column filters,AND/OR/NOT,NEAR,^anchors,bm25()/rankrelevance ordering, andhighlight(), andfts5vocabvocabulary tables — the read-onlydbstatper-page storage introspection table, plusregister_module/register_functionfor your own), and a wide function library — date/time,printf, math, JSON + JSONB, and more — with an index-driven planner andEXPLAIN QUERY PLANmatching sqlite.SELECTnow executes through a register-machine VDBE engine by default (it falls back to the tree-walker for shapes it does not yet compile), with plainEXPLAINlisting the compiled bytecode. Everything is verified differentially againstsqlite3(a 1,600+ query corpus plus 140+ focused suites). R-Tree and FTS5 files are now byte-compatible with sqlite: an FTS5 table written by graphite (stored in sqlite's_content/_data/_idx/_docsize/_configshadow tables) is opened, full-text-MATCHed, and integrity-checked by stocksqlite3, and an R-Tree round-trips through its_nodeon-disk format. (FTS5 sqlite-readability covers ASCII, Latin-1, Latin Extended-A/B, and Latin Extended Additional text — graphite folds diacritics exactly likeunicode61(café→cafe,Dvořák→dvorak,mạ→ma), and honors the fulltokenize=option set —remove_diacritics 0|1|2,porter,ascii, andtokenchars/separators— on both the index and query sides; the fold tables are derived byte-for-byte fromsqlite3; CJK and other scripts pass through unfolded, as in sqlite.) R-Tree queries prune the node tree by the query's coordinate bounds rather than scanning every entry. What remains is depth: finishing the VDBE (per-cursor joins, more single-block shapes) and concurrency — see the full plan in ROADMAP.md.
Why
SQLite is the most-deployed database in the world, but it's C. graphitesql brings
the same file format and SQL dialect to places where a safe, dependency-free,
no_std Rust library shines:
- WebAssembly — run a real SQLite-compatible database in the browser or in a wasm sandbox with no JS shim and no Emscripten.
- Embedded / bare-metal —
no_std+alloc, bring-your-own storage. - Sandboxed / capability-based hosts — no
unsafe, no FFI, no syscalls except through aVfstrait you control.
Goals
- ✅ File-format compatible. Open a database written by
sqlite3; write onesqlite3can open. Verified with differential tests against the C library. - ✅ Safe.
#![forbid(unsafe_code)]across the whole crate. - ✅ Portable.
#![no_std]+alloc. Optionalstdfeature for real files. - ✅ Single crate. Storage, B-tree, SQL parser, and VM all live in
graphitesql. - ✅ No dependencies. Only
coreandalloc.
Non-goals (at least initially)
- Being a faster SQLite. Correctness and compatibility first.
- 100% of every SQLite extension (FTS5, R-Tree, sessions, …). These are layered in later, behind features. See the roadmap.
- Drop-in C ABI (
libsqlite3.so). A C-API shim is a possible future crate, not the core.
Usage
Create a database, write to it, and read it back — and sqlite3 can open it too:
use ;
let mut db = open_memory?; // or Connection::create("app.db")?
db.execute?;
db.execute?;
db.execute?;
let result = db.query?;
for row in &result.rows
// Aggregates, GROUP BY, joins, expressions, scalar functions, transactions:
db.query?;
db.execute?;
db.execute?;
db.execute?;
Open an existing sqlite3-written file with Connection::open("file.db") (or
open_readonly). Low-level format primitives are public too
(graphitesql::format::DatabaseHeader, graphitesql::btree, …).
Command-line shell
The crate ships a graphitesql binary modeled on the sqlite3 CLI:
It accepts ;-terminated SQL (multi-line) and dot-commands: .tables,
.schema [table], .headers on|off, .help, .quit. Results print in
SQLite's default |-separated list mode.
Feature flags
| feature | default | effect |
|---|---|---|
std |
on | std-file Vfs, std::error::Error impl |
fts5 |
on | built-in FTS5 full-text search (MATCH, bm25()/rank, highlight()) |
Disable default features for no_std. An in-memory VFS (:memory:) is always
available, including on wasm. Drop fts5 (e.g. --no-default-features --features std) to build without full-text search.
Building & testing
Reference material & attribution
graphitesql is an independent re-implementation. It uses SQLite's public-domain source and documentation purely as a specification reference — no SQLite code is compiled into this crate. Fetch the (git-ignored, hash-verified) reference tree with:
Deep gratitude to D. Richard Hipp and the SQLite developers. See
NOTICE and ATTRIBUTION.md.
License
Public domain, mirroring SQLite. In place of a legal notice, graphitesql
carries a blessing — see LICENSE. The SPDX identifier is
blessing (the SQLite Blessing).