SQLite

A Whole Database in a Single File — Free of Servers

SQLite

SQLite is perfect for prototypes, single-server apps, and learning. Node 22+ has it built-in.

4 min read Level 1/5 #nodejs#sqlite#database
What you'll learn
  • Open a SQLite database
  • Create a table, insert, query
  • Use prepared statements

SQLite stores the entire database in a single file. No server process. No connection strings. Ridiculously fast for one-machine apps.

Two Ways to Use It

Built-in (Node 22.5+, experimental)

import { DatabaseSync } from "node:sqlite";

const db = new DatabaseSync("app.db");

db.exec(`
  CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT UNIQUE NOT NULL
  )
`);

const insert = db.prepare("INSERT INTO users (name, email) VALUES (?, ?)");
insert.run("Ada", "ada@example.com");

const get = db.prepare("SELECT * FROM users WHERE id = ?");
console.log(get.get(1));

Run with node --experimental-sqlite app.mjs.

npm install better-sqlite3
import Database from "better-sqlite3";

const db = new Database("app.db");

db.prepare(`
  CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT UNIQUE NOT NULL
  )
`).run();

db.prepare("INSERT INTO users (name, email) VALUES (?, ?)")
  .run("Ada", "ada@example.com");

const user = db.prepare("SELECT * FROM users WHERE id = ?").get(1);
console.log(user);

Note: it’s synchronous. SQLite reads/writes are so fast that async overhead would dominate. Just call it directly.

Prepared Statements

Always use parameterized queries — never string-concat user input:

// ✗ SQL injection
db.prepare(`SELECT * FROM users WHERE email = '${email}'`).get();

// ✓ safe
db.prepare("SELECT * FROM users WHERE email = ?").get(email);

Transactions

const insertMany = db.transaction((users) => {
  for (const u of users) {
    db.prepare("INSERT INTO users (name, email) VALUES (?, ?)").run(u.name, u.email);
  }
});

insertMany([
  { name: "Ada",   email: "ada@example.com" },
  { name: "Linus", email: "linus@example.com" },
]);

All-or-nothing, very fast (one fsync at the end).

When to Use SQLite

  • Prototypes, learning, demos
  • Single-server apps with modest write load (small SaaS, internal tools)
  • Edge / CDN deployments (Cloudflare D1, Turso)
  • Local-first apps

When not to: multi-writer high-concurrency apps. SQLite can do ~10K writes/sec on good hardware, but it serializes writes — under heavy concurrent write load, you’ll want Postgres.

PostgreSQL →