Skip to content

Default Node scaffold SQLite to built-in node:sqlite (no native build) #668

@vivek7405

Description

@vivek7405

Problem

A scaffolded Node full-stack app installs better-sqlite3, a NATIVE module that compiles via node-gyp (or fetches a prebuilt binary) at npm install time. That native build is the slowest, most failure-prone part of getting a fresh app to serve. Node 24+ ships a built-in node:sqlite (verified flag-free on Node 26: require('node:sqlite') exposes DatabaseSync / StatementSync), so the default could need no native build at all. The Bun scaffold already avoids this by using the built-in bun:sqlite.

This changes only the DEFAULT. It is NOT package enforcement: better-sqlite3 stays fully supported as an opt-in for anyone who wants it. The point is that the out-of-the-box scaffold should not require a native compile.

Design / approach

Default the Node SQLite dialect's connection to node:sqlite instead of better-sqlite3, mirroring how the Bun scaffold already defaults to bun:sqlite. Reuse the existing per-runtime / per-dialect abstraction (#563 sqlite/postgres dialects, #541 node/bun runtime rewrite) so the change is localized to the connection template + the generator, with the schema/queries/actions untouched.

Open question to resolve during implementation: confirm drizzle-orm has a node:sqlite adapter. drizzle ships drizzle-orm/better-sqlite3 and drizzle-orm/bun-sqlite; if there is no first-class node:sqlite adapter yet, either (a) use the closest compatible adapter, (b) add a thin adapter/shim mapping node:sqlite's DatabaseSync to drizzle's sqlite-proxy, or (c) keep better-sqlite3 as the default until drizzle supports it and ship node:sqlite behind a flag. Decide based on what drizzle actually supports at implementation time.

Implementation notes (for the implementing agent)

  • Where to edit: packages/cli/lib/runtime-rewrite.js (the Add a Bun-first scaffold mode (--runtime bun) across all 3 templates #541 node/bun driver rewrite, where bun:sqlite vs better-sqlite3 is selected), packages/cli/lib/create.js (scaffold generator), and the db/connection.server.ts template the generator emits. Keep the postgres path (pg) unchanged.
  • Node-floor flag: node:sqlite is flag-free on Node 26 but may require --experimental-sqlite on the Node 24 floor. The CLI controls the launch flags for webjs dev / start (packages/cli/bin/webjs.js), so add the flag conditionally on the running Node major if needed, and assert the floor.
  • Landmines: do NOT remove better-sqlite3 support (it stays an opt-in); do NOT change the schema/migration surface (drizzle-kit config); verify webjs db migrate / seed still work against node:sqlite. The four in-repo apps run on Bun (already bun:sqlite), so this default only affects newly-scaffolded Node apps + the node runtime path.
  • Invariants: server-only DB driver stays in db/*.server.ts (AGENTS invariant 1); no native code in pages/components.
  • Tests + docs: test/scaffolds/ (a freshly-scaffolded Node app passes webjs check + webjs test + webjs db migrate); update agent-docs/built-ins.md (DB section), the scaffold templates' DB docs, and the docs-site DB page if it names better-sqlite3 as the default.

Acceptance criteria

  • A freshly-scaffolded Node full-stack app serves + runs webjs db migrate / seed with NO native module build at install (no node-gyp / no prebuilt binary fetch for the DB driver).
  • better-sqlite3 remains a supported opt-in (documented switch), proving this is a default change, not enforcement.
  • The Bun path (bun:sqlite) and the postgres path (pg) are unchanged.
  • test/scaffolds/ covers the node:sqlite default; a counterfactual proves the scaffold actually uses the built-in driver.
  • Docs (built-ins + scaffold + docs site) updated to reflect the new default.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type
No fields configured for issues without a type.

Projects

Status
Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions