{"record":{"id":"4180368f736d43db","repo":"remix-run/remix","slug":"sqlite-config-based-construction-requires-node-sql","errorCode":null,"errorMessage":"SQLite config-based construction requires node:sqlite (Node.js 22.5+) or bun:sqlite; pass a SQLite database client instead","messagePattern":"SQLite config-based construction requires node:sqlite \\(Node\\.js 22\\.5\\+\\) or bun:sqlite; pass a SQLite database client instead","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/data-table-sqlite/src/lib/driver.ts","lineNumber":70,"sourceCode":"// and so bundlers never try to resolve those specifiers statically.\nfunction loadSqliteDatabaseConstructor(): SqliteDatabaseConstructor {\n  if (!loadedDriverConstructor) {\n    if ('Bun' in globalThis) {\n      // import.meta.require is Bun's synchronous require for ES modules; Bun does not\n      // implement process.getBuiltinModule\n      let importMeta = import.meta as ImportMeta & { require?: (id: string) => unknown }\n      let driver = importMeta.require?.('bun:sqlite') as SqliteDriverModule | undefined\n      loadedDriverConstructor = driver?.Database\n    } else {\n      // process.getBuiltinModule loads node:sqlite synchronously (Node.js 22.3+)\n      let driver = globalThis.process?.getBuiltinModule?.('node:sqlite') as\n        | SqliteDriverModule\n        | undefined\n      loadedDriverConstructor = driver?.DatabaseSync\n    }\n\n    if (!loadedDriverConstructor) {\n      throw new Error(\n        'SQLite config-based construction requires node:sqlite (Node.js 22.5+) or bun:sqlite; pass a SQLite database client instead',\n      )\n    }\n  }\n\n  return loadedDriverConstructor\n}\n\n/** Configuration for a SQLite database created by `createSqliteDatabase()`. */\nexport interface SqliteDatabaseConfig {\n  /** SQLite database filename or `:memory:` for an in-memory database. */\n  filename: string\n  /**\n   * Enables SQLite foreign key enforcement whenever the database opens a connection.\n   * Defaults to `false` (enforcement off) on every runtime, including Node.js where\n   * `node:sqlite` would otherwise enable it by default.\n   */\n  foreignKeys?: boolean","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/remix-run/remix/blob/9696913134be3a4423513d2775f7b31d6917c049/packages/data-table-sqlite/src/lib/driver.ts#L52-L88","documentation":"For config-based construction the SQLite driver dynamically imports node:sqlite (Node 22.5+) or bun:sqlite to get DatabaseSync. If neither module exists in the runtime, this error tells you to either upgrade the runtime or pass an already-open database client.","triggerScenarios":"Running on Node < 22.5 (e.g. Node 18/20/22.0) or a non-Bun runtime and constructing the SQLite driver with a config object (filename/options) instead of a client instance; bundlers stripping the dynamic imports.","commonSituations":"Deploying to LTS Node images older than 22.5; running tests under Node 20 while developing under Bun; serverless runtimes without node:sqlite.","solutions":["Upgrade to Node 22.5+ (or run under Bun) so node:sqlite is available","Otherwise construct the driver with an existing client: new SqliteDatabase(client) using node:sqlite's DatabaseSync, better-sqlite3, or bun:sqlite","Pin/verify the runtime version in CI to match the SQLite requirements"],"exampleFix":"// before\nnew SqliteDatabase({ filename: './app.db' }) // throws on Node 20\n\n// after\nimport { DatabaseSync } from 'node:sqlite' // Node 22.5+\nnew SqliteDatabase(new DatabaseSync('./app.db'))","handlingStrategy":"type-guard","validationCode":"import { isSqliteRuntimeSupported } from './runtime-check' // or check manually\nconst major = parseInt(process.versions.node.split('.')[0], 10)\nconst minor = parseInt(process.versions.node.split('.')[1] ?? '0', 10)\nconst supported = process.versions.bun || (major === 22 && minor >= 5) || major > 22","typeGuard":"function supportsNodeSqlite(): boolean {\n  if (process.versions.bun) return true\n  const [maj, min] = process.versions.node.split('.').map(Number)\n  return maj > 22 || (maj === 22 && min >= 5)\n}","tryCatchPattern":null,"preventionTips":["Pin Node >= 22.5 in engines and CI","Fall back to constructing with an explicit client on older runtimes","Test on the same runtime family you deploy"],"tags":["sqlite","node-version","runtime","driver"],"backgroundTag":"unsupported-runtime-version","analyzedSha":"9696913134be3a4423513d2775f7b31d6917c049","analyzedAt":"2026-08-27T19:55:01.024Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}