🚀 Introducing Postgres Lite: A Pure JS Embedded Engine for Node.js, Bun, and the Browser
PostgreSQL is arguably the most loved database in the world. But when it comes to local-first development, edge computing, or browser-based apps, we usually reach for SQLite.
Why? Because running a full Postgres instance in the browser or as a zero-dependency embedded process in Node/Bun has traditionally been hard—requiring heavy WASM binaries or network proxies.
Today, I'm excited to introduce Postgres Lite (PGLite): An ultra-lightweight, high-performance, in-process PostgreSQL engine built natively for the JavaScript ecosystem.
🛠 What is Postgres Lite?
Postgres Lite is a custom-built SQL engine that implements the PostgreSQL dialect using pure TypeScript/JavaScript. It’s designed to be a robust SQLite alternative that speaks "Postgres," allowing you to use the same schemas, queries, and logic from your backend directly in the frontend or local environments.
- Zero Emulation: No WASM overhead.
- Zero Dependency: Just pure JS/TS logic.
- Universal: Runs in Bun, Node.js, and Modern Browsers (via IndexedDB).
🏗 The Engineering Behind the Performance
Building a database engine from scratch requires more than just parsing SQL. Postgres Lite implements several advanced database engineering techniques to ensure it can handle 1M+ records with ease:
1. Slotted Page Layout
Unlike simple JSON stores, PGLite organizes data into fixed 4KB pages using a slotted-page architecture. This prevents fragmentation and allows for efficient management of variable-length records (like JSONB or TEXT).
2. B-Tree Indexing & O(log n) Lookups
Primary keys and unique constraints are backed by a persistent B-Tree implementation. This ensures that even as your dataset grows to millions of rows, point lookups remain lightning-fast.
3. Write-Ahead Logging (WAL) & ACID Compliance
Data integrity is non-negotiable. PGLite implements WAL. Every mutation is logged to a persistent .wal file before being applied to the main storage. If your process crashes, the engine automatically replays the WAL on the next boot.
4. Volcano Execution Model
PGLite uses an iterator-based processing model. Rows are "pulled" through the execution plan one by one. This means a SELECT * on a million-row table uses a constant and minimal memory footprint instead of loading everything into RAM.
5. LRU Buffer Pool
A sophisticated Least-Recently-Used (LRU) cache manages memory, keeping frequently accessed pages hot and minimizing physical I/O to the disk or IndexedDB.
🚦 Quick Start
Installation
npm install @pglite/core
# or
bun add @pglite/core
Usage in Node.js/Bun
import { PGLite } from "@pglite/core";
import { NodeFSAdapter } from "@pglite/core/node-fs";
const db = new PGLite("app.db", { adapter: new NodeFSAdapter() });
await db.exec(`
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
metadata JSONB
)
`);
await db.exec("INSERT INTO users (name, metadata) VALUES ($1, $2)",
["Alice", { role: "admin" }]
);
const results = await db.query("SELECT * FROM users WHERE name = $1", ["Alice"]);
console.table(results);
Usage in the Browser
import { PGLite } from "@pglite/core";
import { BrowserFSAdapter } from "@pglite/core/browser";
const db = new PGLite("browser_storage", { adapter: new BrowserFSAdapter() });
// Everything else is the same!
⚡️ Supported Features
Despite its "Lite" name, the engine supports a vast subset of Postgres syntax:
-
Complex Joins:
INNER,LEFT,LATERAL, andCROSS JOIN. -
Advanced Querying: CTEs (
WITH),UNION,INTERSECT, and Subqueries. -
Window Functions:
ROW_NUMBER(),RANK()viaOVER (PARTITION BY...). -
JSON Power: Full support for
JSONBoperators (->,->>,@>,?). -
Upserts:
ON CONFLICT (col) DO UPDATE SET ...
📊 Performance Benchmark
In our internal tests:
- Point Lookups (PK): ~0.2ms - 0.5ms.
- Sequential Scan: 100k rows in < 40ms.
- Memory Usage: Constant under heavy query load thanks to the Volcano model.
If you are a database enthusiast or a JS developer looking for a better way to handle local data, check out the project on GitHub!
https://github.com/pglite/pglite
Follow me for more deep dives into systems programming with JavaScript!
Top comments (0)