v3/implementation/research/better-sqlite3-usage-inventory.md
Generated: 2026-01-03 Purpose: Complete inventory of better-sqlite3 usage across codebase for sql.js migration
File: /home/user/claude-flow/src/memory/sqlite-wrapper.js
// Lines 14-19
let Database = null;
let sqliteAvailable = false;
let loadError = null;
let rebuildAttempted = false;
// Line 54-66: Loading logic
async function tryLoadSQLite() {
try {
const require = createRequire(import.meta.url);
Database = require('better-sqlite3');
sqliteAvailable = true;
return true;
} catch (requireErr) {
// Fallback to ES module import
// ... error handling
}
}
File: /home/user/claude-flow/src/api/database-service.ts
initializeSQLite()// Line 556-570
private async initializeSQLite(): Promise<void> {
try {
// Import better-sqlite3 dynamically
const Database = (await import('better-sqlite3')).default;
this.db = new Database(this.config.database);
// Enable WAL mode for better concurrency
this.db.pragma('journal_mode = WAL');
this.db.pragma('synchronous = NORMAL');
this.db.pragma('cache_size = 1000');
this.db.pragma('temp_store = memory');
} catch (error) {
throw new DatabaseError('Failed to initialize SQLite', { error });
}
}
File: /home/user/claude-flow/src/core/DatabaseManager.ts
SQLiteProvider constructor// Line 189-207
class SQLiteProvider implements IDatabaseProvider {
private db: any;
private dbPath: string;
constructor(dbPath: string) {
this.dbPath = dbPath;
// Dynamic import to handle optional dependency
try {
const Database = require('better-sqlite3'); // Line 197
this.db = new Database(dbPath);
} catch (error) {
// Check for native module version mismatch (NODE_MODULE_VERSION error)
if (isNativeModuleVersionError(error)) {
const recoveryMsg = getNativeModuleRecoveryMessage(error);
throw new NativeModuleError(recoveryMsg, error as Error);
}
throw new Error('better-sqlite3 not available. Install with: npm install better-sqlite3');
}
}
}
File: /home/user/claude-flow/src/core/persistence.ts
// Line 1-8
/**
* Persistence layer for Claude-Flow using SQLite
*/
import Database from 'better-sqlite3'; // Line 5
import { join } from 'path';
import { mkdir } from 'fs/promises';
Methods using better-sqlite3:
initialize() - Line 44-53createTables() - Line 55-100saveAgent() - Line 103-120getAgent() - Line 122-139File: /home/user/claude-flow/src/memory/backends/sqlite.ts
sqlite-wrapper.js// Line 32-38: Dynamic import from wrapper
if (!this.sqliteLoaded) {
const module = await import('../sqlite-wrapper.js');
createDatabase = module.createDatabase;
isSQLiteAvailable = module.isSQLiteAvailable;
this.sqliteLoaded = true;
}
File: /home/user/claude-flow/src/memory/sqlite-store.js
// Line 1-12
import path from 'path';
import { promises as fs } from 'fs';
import { fileURLToPath } from 'url';
import os from 'os';
import { createDatabase } from './sqlite-wrapper.js'; // Line 10
import { getSwarmDir } from '../utils/project-root.js';
import { sessionSerializer } from './enhanced-session-serializer.js';
File: /home/user/claude-flow/src/cli/simple-commands/hive-mind.js
// Line 36-49
try {
Database = require('better-sqlite3'); // Line 38
DatabaseAvailable = true;
} catch (error) {
console.warn('⚠️ better-sqlite3 not available, falling back to in-memory storage');
try {
// Try ES module import
const sqlite = await import('better-sqlite3'); // Line 46
Database = sqlite.default;
DatabaseAvailable = true;
} catch (importError) {
// Fallback handled
}
}
File: /home/user/claude-flow/src/cli/simple-commands/hive-mind-wizard.js
// Line 1-10
const fs = require('fs-extra');
const path = require('path');
const Database = require('better-sqlite3'); // Line 4
const ora = require('ora');
File: /home/user/claude-flow/src/cli/simple-commands/hive-mind/memory.js
// Line 1-10
/**
* Hive Mind Memory Management CLI
*/
import fs from 'fs-extra';
import path from 'path';
import Database from 'better-sqlite3'; // Line 7
File: /home/user/claude-flow/src/cli/simple-commands/hive-mind/metrics-reader.js
// Line 1-10
/**
* Hive Mind Metrics Reader
*/
import fs from 'fs-extra';
import path from 'path';
import Database from 'better-sqlite3'; // Line 6
File: /home/user/claude-flow/src/cli/simple-commands/hive-mind/db-optimizer.js
// Line 1-12
/**
* Hive Mind Database Optimizer
*/
import fs from 'fs-extra';
import path from 'path';
import os from 'os';
import Database from 'better-sqlite3'; // Line 8
File: /home/user/claude-flow/src/cli/simple-commands/hive-mind/mcp-wrapper.js
// Line 132
/** @type {import('better-sqlite3').Database | null} */
this.db = null;
File: /home/user/claude-flow/src/cli/simple-commands/init/hive-mind-init.js
// Line 304-315
// Dynamic import for better-sqlite3 with proper error handling
let Database;
try {
Database = (await import('better-sqlite3')).default; // Line 307
console.log('✅ Using SQLite for persistent storage');
} catch (error) {
console.warn('⚠️ SQLite not available, using in-memory storage');
console.warn(' Install better-sqlite3 for persistence: npm install better-sqlite3');
useInMemory = true;
}
File: /home/user/claude-flow/src/cli/simple-commands/swarm-metrics-integration.js
// Line 1-12
/**
* Swarm Metrics Integration Service
*/
import fs from 'fs-extra';
import path from 'path';
import Database from 'better-sqlite3'; // Line 8
File: /home/user/claude-flow/src/utils/error-recovery.ts
isNpmCacheError() - Line 28-34isNativeModuleVersionError() - Line 40-46getNativeModuleRecoveryMessage() - Line 52-80verifyBetterSqlite3() - Line 267-274// Line 28-34
export function isNpmCacheError(error: any): boolean {
const errorStr = error?.message || String(error);
return (
errorStr.includes('ENOTEMPTY') &&
(errorStr.includes('npm') || errorStr.includes('npx') || errorStr.includes('_npx'))
) || errorStr.includes('better-sqlite3'); // Line 33
}
File: /home/user/claude-flow/scripts/fix-agentic-flow-sqlite.sh
# Line 6
QUERIES_FILE="node_modules/agentic-flow/dist/reasoningbank/db/queries.js"
# Line 16
if grep -q "import Database from 'better-sqlite3'" "$QUERIES_FILE"; then
# Line 25-26
sed -i '5s/const BetterSqlite3 = null; \/\/ Not used/import Database from '\''better-sqlite3'\'';/' "$QUERIES_FILE"
sed -i 's/new BetterSqlite3(/new Database(/g' "$QUERIES_FILE"
File: /home/user/claude-flow/src/patches/hive-mind-timezone-fix.patch
# Line 77
+ import Database from 'better-sqlite3';
Package: agentic-flow@^1.9.4
dist/reasoningbank/db/queries.jsImpact: Medium - Disables ReasoningBank features on Windows
Package: agentdb@^1.6.1
patches/agentdb-fix-imports.patchImpact: Medium - Disables vector search on Windows
File: /home/user/claude-flow/scripts/install-arm64.js
// Line 7-16
async function checkSqliteBindings() {
try {
const Database = await import('better-sqlite3'); // Line 9
const db = new Database.default(':memory:'); // Line 11
db.close();
return true;
} catch (error) {
// Silently fail - this is expected when better-sqlite3 doesn't compile
return false;
}
}
Each modified file should have:
| File | Lines to Change | Complexity | Hours |
|---|---|---|---|
| sqlite-wrapper.js | ~100 | High | 8 |
| DatabaseManager.ts | ~50 | Medium | 4 |
| backends/sqljs.ts (new) | ~350 | High | 12 |
| persistence.ts | ~20 | Low | 2 |
| database-service.ts | ~10 | Low | 1 |
| error-recovery.ts | ~30 | Medium | 3 |
| CLI files (9) | ~5 each | Low | 5 |
| Tests (new) | ~500 | High | 16 |
| Documentation | N/A | Medium | 8 |
| Total | ~1065 | - | 59 hours |
Estimated timeline: ~8 working days (1 developer)
// Before
import Database from 'better-sqlite3';
const db = new Database('path/to/db.sqlite');
// After
import { createDatabase } from './sqlite-wrapper.js';
const db = await createDatabase('path/to/db.sqlite');
// Before
const Database = (await import('better-sqlite3')).default;
// After
const { createDatabase } = await import('./sqlite-wrapper.js');
const db = await createDatabase(dbPath);
// Before
const Database = require('better-sqlite3');
// After
const { createDatabase } = require('./sqlite-wrapper.js');
// (or migrate to ESM)
Document Version: 1.0 Last Updated: 2026-01-03 Status: Complete inventory for migration planning