← Back to PRs

#8706: fix(memory): fall back to better-sqlite3 when node:sqlite lacks FTS5

by ElmerProject open 2026-02-04 09:15 View on GitHub →
stale
## Summary Node.js's built-in `node:sqlite` module doesn't include FTS5 support by default. This causes the memory search FTS (full-text search) feature to be unavailable for many users, showing the error: `no such module: fts5`. This PR adds automatic detection and transparent fallback to `better-sqlite3` (if installed) when FTS5 is not available in `node:sqlite`. ## Changes - Add FTS5 availability check on first database open via in-memory test - Create `BetterSqliteDatabaseSync` wrapper class matching the `node:sqlite` `DatabaseSync` interface - Add `better-sqlite3` as optional peer dependency (users who need FTS5 can install it) - Fall back transparently without any user intervention or configuration - Cache the detection result to avoid repeated testing ## How it works 1. On first `requireNodeSqlite()` call, test if FTS5 is available in `node:sqlite` by creating a temp in-memory database and attempting to create an FTS5 virtual table 2. If FTS5 works, use `node:sqlite` (no change in behavior) 3. If FTS5 fails and `better-sqlite3` is installed, use a wrapper class that provides the same interface 4. If neither works, fall back to `node:sqlite` without FTS5 (graceful degradation, same as current behavior) ## Test plan - [x] Build passes (`pnpm build`) - [x] Lint passes for modified files - [ ] Install better-sqlite3 and verify FTS5 works - [ ] Remove better-sqlite3 and verify graceful fallback - [ ] Test with node:sqlite FTS5 (if building Node.js with FTS5 enabled) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR adds an FTS5 capability probe around `node:sqlite` and introduces a transparent fallback to `better-sqlite3` when FTS5 isn’t available, so memory full-text search can continue to work on Node builds lacking FTS5. Core behavior is centralized in `src/memory/sqlite.ts`, where `requireNodeSqlite()` now caches an FTS5 availability result and either returns the native `node:sqlite` module or a `DatabaseSync`-compatible wrapper backed by `better-sqlite3`. The root `package.json` is updated to make `better-sqlite3` an optional peer dependency (and adds `@types/better-sqlite3` for TS), with corresponding lockfile updates, and the changelog notes the user-facing fix. <h3>Confidence Score: 3/5</h3> - This PR is likely safe to merge, but there are a couple of type/interface correctness issues that could cause maintenance or runtime surprises. - The overall approach (capability probing + cached fallback) is straightforward, but the wrapper’s typing is currently incorrect and the module-level cast to `typeof node:sqlite` can mask missing exports; those are the main risks to correctness over time. The changelog PR number mismatch is also a clear fix. - src/memory/sqlite.ts, CHANGELOG.md <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs