PGlite is a WASM Postgres build packaged into a TypeScript client library that enables you to run Postgres in the browser, Node.js and Bun, with no need to install any other dependencies. It is only 3.7mb gzipped and provides a complete PostgreSQL database implementation with both ephemeral in-memory database capabilities and persistent storage options.
npm install @electric-sql/pgliteimport { PGlite } from "@electric-sql/pglite";For CommonJS:
const { PGlite } = require("@electric-sql/pglite");Additional exports:
import {
MemoryFS,
IdbFs,
uuid,
formatQuery,
types,
parse,
messages,
protocol,
Mutex
} from "@electric-sql/pglite";MemoryFS, IdbFs - Filesystem implementationsuuid, formatQuery - Utility functionstypes, parse - Type system and parsing utilitiesmessages, protocol - PostgreSQL wire protocol utilities from @electric-sql/pg-protocolMutex - Concurrency control from async-muteximport { PGlite } from "@electric-sql/pglite";
// Create an in-memory database
const db = new PGlite();
await db.waitReady;
// Create a table and insert data
await db.exec(`
CREATE TABLE IF NOT EXISTS todo (
id SERIAL PRIMARY KEY,
task TEXT,
done BOOLEAN DEFAULT false
);
`);
// Insert data
await db.query("INSERT INTO todo (task, done) VALUES ($1, $2)", [
"Learn PGlite",
false,
]);
// Query data
const results = await db.query("SELECT * FROM todo WHERE done = $1", [false]);
console.log(results.rows);
// Close the database
await db.close();PGlite is built around several key components:
PGlite class providing the main database interface with full PostgreSQL compatibilityMemoryFS, IdbFs, NodeFS, OpfsAhpFS) for different storage backendsMain database class providing PostgreSQL query execution, transaction management, and database lifecycle operations.
class PGlite {
constructor(dataDir?: string, options?: PGliteOptions);
constructor(options?: PGliteOptions);
readonly waitReady: Promise<void>;
readonly ready: boolean;
readonly closed: boolean;
readonly dataDir?: string;
query<T>(query: string, params?: any[], options?: QueryOptions): Promise<Results<T>>;
sql<T>(strings: TemplateStringsArray, ...params: any[]): Promise<Results<T>>;
exec(query: string, options?: QueryOptions): Promise<Array<Results>>;
transaction<T>(callback: (tx: Transaction) => Promise<T>): Promise<T>;
close(): Promise<void>;
}
interface Results<T = Record<string, any>> {
rows: Row<T>[];
affectedRows?: number;
fields: { name: string; dataTypeID: number }[];
blob?: Blob;
}Multiple filesystem implementations for different environments and persistence requirements.
class MemoryFS implements Filesystem {
constructor();
}
class IdbFs implements Filesystem {
constructor(dataDir: string);
}
interface Filesystem {
readonly fsType: FsType;
syncToFs(mod: any): Promise<void>;
dumpTar(mod: any, compression?: DumpTarCompressionOptions): Promise<File | Blob>;
}Safe SQL query composition with template literals and parameter interpolation.
function sql(strings: TemplateStringsArray, ...values: any[]): TemplateContainer;
function query(strings: TemplateStringsArray, ...values: any[]): TemplatedQuery;
function identifier(strings: TemplateStringsArray, ...values: any[]): TemplatePart;
function raw(strings: TemplateStringsArray, ...values: any[]): TemplatePart;Real-time query results with automatic updates when underlying data changes.
interface LiveNamespace {
query<T>(query: string, params?: any[], key?: string): Promise<LiveQuery<T>>;
incrementalQuery<T>(query: string, params?: any[], key?: string): Promise<LiveQuery<T>>;
changes<T>(query: string, params?: any[], key?: string): Promise<LiveChanges<T>>;
}
interface LiveQuery<T> {
initialResults: Results<T>;
refresh(): Promise<Results<T>>;
unsubscribe(): Promise<void>;
}Multi-tab shared database access through dedicated or shared worker threads.
class PGliteWorker extends BasePGlite {
constructor(worker: Worker, options?: PGliteWorkerOptions);
}
function worker(options?: WorkerOptions): void;Pluggable architecture for adding PostgreSQL extensions and custom functionality.
interface Extension<T = any> {
name: string;
setup: ExtensionSetup<T>;
}
type ExtensionSetup<TNamespace = any> = (
pg: PGliteInterface,
emscriptenOpts: any,
clientOnly?: boolean
) => Promise<ExtensionSetupResult<TNamespace>>;PostgreSQL pgvector extension for vector similarity search and operations.
const vector: Extension;interface PGliteOptions<TExtensions = Record<string, Extension>> {
dataDir?: string;
username?: string;
database?: string;
fs?: Filesystem;
debug?: DebugLevel;
relaxedDurability?: boolean;
extensions?: TExtensions;
loadDataDir?: Blob | File;
initialMemory?: number;
wasmModule?: WebAssembly.Module;
fsBundle?: Blob | File;
parsers?: ParserOptions;
serializers?: SerializerOptions;
defaultDataTransferContainer?: DataTransferContainer;
}
interface QueryOptions {
rowMode?: 'array' | 'object';
parsers?: ParserOptions;
serializers?: SerializerOptions;
blob?: Blob | File;
onNotice?: (notice: NoticeMessage) => void;
paramTypes?: number[];
}
type DebugLevel = 0 | 1 | 2 | 3 | 4 | 5;
type Row<T> = T extends Record<string, any> ? T : Record<string, any>;
type DataTransferContainer = 'cma' | 'file';