Skip to main content
Meet

PostgreJS

Blazing Fast PostgreSQL Client

Up to 6.6× faster than its competitors — a binary wire protocol built from scratch, with nothing slowing it down.

Blazing Fast.

Up to 6.6× faster than the competition in pooled-query benchmarks — with a smaller peak-heap footprint in almost every scenario.

One package. Everything included.

Cursors, prepared statements, LISTEN/NOTIFY, COPY streams, large objects, logical replication, multi-host failover, two-phase commit — all built in, not scattered across a half-dozen add-on packages.

Binary by default.

The only one of the three that speaks binary both ways — encoding parameters and decoding results — for every supported type, with per-column control when you still want text.

Query the way the moment calls for.

A parameterized query for one row, or a cursor when the result set doesn't fit in memory — same connection, same options.

A parameterized query
import { Connection } from 'postgrejs';

const connection = new Connection('postgres://localhost/mydb');
await connection.connect();

const result = await connection.query(
'select * from cities where name like $1',
{ params: ['%york%'] },
);
console.log(result.rows);
Streaming a large result with a cursor
import { Connection } from 'postgrejs';

const connection = new Connection('postgres://localhost/mydb');
await connection.connect();

const result = await connection.query(
'select * from cities', { cursor: true },
);
let row;
while ((row = await result.cursor.next())) {
console.log(row);
}
await result.cursor.close();

Everything a PostgreSQL client should do

Speaks binary, not just text.

Full binary wire protocol for every supported PostgreSQL type, with per-column format selection — a control most drivers don’t expose at all.

Named statements. Streaming cursors.

Explicit, reusable prepared statements, and server-side cursors that stream a large result set instead of buffering all of it in memory.

TypeScript, all the way down.

Every config field, query option, and result row is typed — the compiler catches what a stale JSDoc comment would only suggest.

Compose SQL, not strings.

The sql tag builds parameterized statements from fragments — sql.values() and sql.set() turn a plain object into an INSERT or UPDATE clause.

COPY, large objects, logical replication.

Bulk import/export as Node streams, file-like access to data too big for a column, and pgoutput change streaming — all in the one package.

Finds the primary on its own.

List several hosts and a target role — read-write, standby, prefer-standby — and postgrejs picks the right server the same way libpq does.

How postgrejs compares

Checked against the source of pg and postgres.js, not their documentation.

The usual way
With postgrejs

Parameters get stringified before they’re sent, and results come back as text — every round trip pays a decoding tax.

Binary wire format by default, both directions. Pooled queries run up to 6.6× faster than the competition.

Cursors, COPY, large objects, logical replication — pieced together from several separately-maintained packages, if they exist at all.

All of it in the one package: cursors, prepared statements, COPY streams, large objects, logical replication, multi-host failover, two-phase commit.

Binary decoding is often partial — a missing parser for a common type, or an array decoder that only handles a few element types correctly.

56 types encode and decode correctly in both text and binary, verified by a test suite that runs on every push against PostgreSQL 12 through 18.

No transaction API, or one without two-phase commit for coordinating a commit across connections.

Transactions, savepoints, and two-phase commit — prepareTransaction() today, commitPrepared() from anywhere, later.

One connection, one host. A failover means reconfiguring and reconnecting by hand.

List several hosts and a target role; postgrejs finds the current primary automatically, on the next connect.

An async error’s stack trace points into the driver’s own internals, not the line that called it.

Errors keep your own call site in the stack — and point at the exact line and column in the SQL that failed.

See the full feature comparison table for every row and its footnotes.

Ready to connect?

Install postgrejs and run your first query in a few lines.

Read the docs →