Skip to content

SQLite (local)

The SQLite store uses Bun’s built-in SQLite driver (bun:sqlite). No separate driver package is needed. The database file is created automatically on first use.

Terminal window
bun add -D @flaky-tests/store-sqlite
import { SqliteStore } from '@flaky-tests/store-sqlite'
const store = new SqliteStore()
// or with a custom path:
const store = new SqliteStore({ dbPath: './data/tests.db' })

The SqliteStore constructor opens (or creates) the database file and schedules migrate() — tables and any pending schema migrations are applied before subsequent operations. Migrations are versioned and tracked in a schema_version table, so migrate() is idempotent and safe to call on every startup. The CLI auto-runs migrate() before every query.

interface SqliteStoreOptions {
/** Path to the SQLite file. Default: node_modules/.cache/flaky-tests/failures.db */
dbPath?: string
}

The store creates runs and failures tables and applies versioned migrations from SQLITE_MIGRATIONS. The current schema includes fields like project, git_sha, git_dirty, status, duration_ms, and per-failure error_message / error_stack / duration_ms. See packages/core/src/migrations/sqlite.ts for the authoritative schema.

Driver errors are wrapped in StoreError with cause preserved. Read methods (getNewPatterns, getRecentRuns) accept an optional signal?: AbortSignal. Because bun:sqlite is synchronous, the signal is only checked on entry via throwIfAborted() — there is no mid-query cancellation.

You can query the database directly with any SQLite client:

Terminal window
# With Bun
bun run -e "
const { Database } = require('bun:sqlite')
const db = new Database('node_modules/.cache/flaky-tests/failures.db')
console.log(db.query('SELECT * FROM failures ORDER BY failed_at DESC LIMIT 20').all())
"
# With sqlite3 CLI
sqlite3 node_modules/.cache/flaky-tests/failures.db \
"SELECT test_name, count(*) as fails FROM failures GROUP BY test_name ORDER BY fails DESC"