2.7 KiB
ADR-001: SQLite Library Choice
Date: 2026-03-23
Status: Accepted
Decision: Use sql.js instead of better-sqlite3
Context
During MVP development (iteration 3), better-sqlite3 failed to build on WSL2 with Node.js v22.22.0:
error: 'class v8::ObjectTemplate' has no member named 'SetAccessor'
gyp ERR! build error
Root cause: better-sqlite3 native bindings are not compatible with Node.js v22's V8 API changes.
Options considered:
-
Downgrade Node.js to v20 LTS
- ❌ Impacts other workspace projects
- ❌ Not sustainable long-term
-
Wait for better-sqlite3 update
- ❌ Blocks autonomous development
- ❌ Timeline uncertain
-
Switch to sql.js (pure JavaScript SQLite)
- ✅ Zero native dependencies
- ✅ Works everywhere (WSL2, Docker, browser)
- ✅ Synchronous API available
- ⚠️ Slightly slower than native (acceptable for single-household use)
-
Switch to node-sqlite3 (callback-based)
- ⚠️ Async API violates ARCHITECTURE.md sync preference
- ⚠️ May have similar v22 compatibility issues
Decision
Use sql.js (https://github.com/sql-js/sql.js) for MVP and beyond.
Rationale:
- Enables autonomous overnight agent work (no environment blockers)
- Synchronous API matches original architecture vision
- Pure JavaScript = portable across all environments
- Performance difference negligible for ~1000 recipes
- Can persist to filesystem same as better-sqlite3
Implementation Notes
Package: sql.js (npm install sql.js)
Usage pattern:
import initSqlJs from 'sql.js';
const SQL = await initSqlJs();
const db = new SQL.Database();
// ... same SQL queries as before
Persistence:
// Save to file
const data = db.export();
fs.writeFileSync('data/recipes.db', Buffer.from(data));
// Load from file
const buffer = fs.readFileSync('data/recipes.db');
db = new SQL.Database(buffer);
Migration path:
- If future performance issues arise, can revisit when better-sqlite3 supports Node v22+
- Database file format is standard SQLite (portable)
Consequences
Positive:
- ✅ Unblocked autonomous development
- ✅ Zero native build dependencies
- ✅ Easier Docker deployment
- ✅ Works in browser (future PWA feature)
Negative:
- ⚠️ ~10-20% slower than native bindings (negligible for our use case)
- ⚠️ Requires explicit save() calls (better-sqlite3 auto-persists)
Neutral:
- Same SQL syntax and database schema
- Same overall architecture (just the driver changes)
Status
Accepted — 2026-03-23
Documented environment blocker, evaluated alternatives, chose pragmatic path forward per agent-harness methodology (keep moving vs block on environment).