Usage with PGlite
MikroORM supports PGlite — a WASM build of PostgreSQL that runs in Node.js, the browser, Bun and Deno without a separate database server. The @mikro-orm/pglite driver reuses the full @mikro-orm/postgresql SQL/schema/migrations stack via @mikro-orm/sql, so feature support matches the regular PostgreSQL driver.
Installation
- npm
- Yarn
- pnpm
- Bun
npm install @mikro-orm/core @mikro-orm/pglite
yarn add @mikro-orm/core @mikro-orm/pglite
pnpm add @mikro-orm/core @mikro-orm/pglite
bun add @mikro-orm/core @mikro-orm/pglite
Configuration
PGlite defaults to in-memory storage; pass a dbName only when you want to persist the database.
import { defineConfig } from '@mikro-orm/pglite';
export default defineConfig({
entities: ['./dist/entities'],
entitiesTs: ['./src/entities'],
});
Storage backends
The dbName option selects the PGlite storage backend:
// in-memory (default)
await MikroORM.init({ entities: [...] });
// persisted to a Node.js directory
await MikroORM.init({ entities: [...], dbName: './my-db' });
// persisted to IndexedDB (browser)
await MikroORM.init({ entities: [...], dbName: 'idb://my-db' });
See the PGlite documentation for the full list of supported dataDir schemes.
Driver options
Anything passed under driverOptions is forwarded to PGlite.create(), so you can register extensions, custom type parsers, etc.
import { defineConfig } from '@mikro-orm/pglite';
import { vector } from '@electric-sql/pglite/vector';
export default defineConfig({
entities: [...],
dbName: './my-db',
driverOptions: {
extensions: { vector },
},
});
Named databases inside a cluster
By default dbName is the PGlite cluster location (the dataDir), so each database lives in its own directory. If you point driverOptions.dataDir at the cluster explicitly, dbName instead selects a named database within that cluster (PGlite's database option), just like a regular PostgreSQL server:
import { defineConfig } from '@mikro-orm/pglite';
export default defineConfig({
entities: [...],
dbName: 'app', // a database inside the cluster
driverOptions: {
dataDir: './cluster', // the cluster location
},
});
The database lifecycle then behaves like a regular PostgreSQL server — orm.schema.ensureDatabase() and the database:create/database:drop commands run real CREATE DATABASE/DROP DATABASE statements against the cluster. This requires a persistent dataDir (file or idb://) and is not available for in-memory clusters.
Reusing an existing PGlite instance
Pass an existing PGlite instance (or async factory) under driverOptions.pglite if you need to share it with non-ORM code, run multiple ORMs against the same database, or pre-load the WASM module yourself. MikroORM will not own the lifecycle — closing the ORM leaves your instance untouched, and the default type parsers are not applied (configure them on your own instance).
import { PGlite } from '@electric-sql/pglite';
import { MikroORM } from '@mikro-orm/pglite';
const pglite = await PGlite.create({ dataDir: './my-db' });
const orm = await MikroORM.init({
entities: [...],
driverOptions: { pglite },
});
Schema, migrations, and queries
PGlite implements standard PostgreSQL features, so the Schema Generator, Migrations, QueryBuilder, and Kysely integration all work the same way as with @mikro-orm/postgresql.
Limitations
- Streaming is not supported — PGlite does not expose cursor-based streaming. Use
@mikro-orm/postgresqlagainst a real PostgreSQL server if you needem.stream()orqb.stream().