pg (node-postgres) is a robust and non-blocking PostgreSQL client for Node.js, providing both a pure JavaScript implementation and optional native `libpq` bindings, both exposing the exact same API. Currently at version 8.20.0, the library maintains an active development pace with regular updates and bug fixes, indicated by its consistent major version releases and community support. Key features include efficient connection pooling, extensible data-type coercion between JavaScript and PostgreSQL types, support for parameterized queries to prevent SQL injection, named statements with query plan caching, and asynchronous notifications via `LISTEN/NOTIFY`. It also facilitates bulk data operations using `COPY TO/COPY FROM`. Its design prioritizes being a light abstraction layer, encouraging users to leverage companion modules for higher-level ORM or query building needs.
npm install pgVerified import paths — ran on the pinned version, not inferred.
This quickstart demonstrates how to use `pg` with connection pooling, parameterized queries for safety, and basic database setup/teardown. It utilizes environment variables for configuration and handles connection acquisition and release from the pool.
If connecting to a database with a self-signed certificate, explicitly set `ssl: { rejectUnauthorized: false }` in your Client or Pool configuration: `const pool = new Pool({ ssl: { rejectUnauthorized: false } });`Replace `pg.connect()` with `pool.connect()` after instantiating a `new Pool()` object. Similarly, replace `pg.end()` with `pool.end()`. See the official migration guide for more details.
Refactor code using `client.query().on('row', ...)` or other event emitter patterns. For streaming, use `pg-cursor` or `pg-query-stream`. For simple queries, use async/await with the promise returned by `client.query()` without a callback.Always ensure `client.release()` is called in a `finally` block after acquiring a client with `pool.connect()`, regardless of whether the database operations succeeded or failed.
Always use parameterized queries. Pass an array of values as the second argument to `client.query(text, values)` to let `pg` handle safe parameter substitution. For dynamic identifiers (table/column names), use a library like `pg-format` for proper escaping.
Ensure `libpq-dev` (or equivalent for your OS, e.g., `postgresql-devel` on RHEL, `libpq` on macOS via Homebrew) and a C++ compiler are installed before `npm install pg-native`. If `pg-native` is not strictly necessary for performance, `pg` will gracefully fall back to its pure JavaScript implementation.
Verify `PGUSER`, `PGPASSWORD`, `PGDATABASE`, `PGHOST`, `PGPORT` environment variables or the respective properties in the `Client`/`Pool` config object. Ensure the PostgreSQL user exists and has the correct password.
Ensure `client.end()` is not called prematurely for long-lived clients or that you are always acquiring a fresh client from the `Pool` for each logical unit of work, releasing it afterward. For transactions, ensure all queries are executed on the *same* `Client` instance acquired from the `Pool` until the transaction is committed or rolled back.
Edit your PostgreSQL server's `pg_hba.conf` file to add an appropriate entry allowing connections from your application's host with the specified user, database, and authentication method (e.g., `host all all 0.0.0.0/0 md5` for broad access with password or `hostssl all all 0.0.0.0/0 scram-sha-256` for secure access).
Ensure you are using `pg@8.15.x` or newer for full ESM support. If you must use an older version or are in a mixed CJS/ESM environment, use `import pg from 'pg'; const { Pool } = pg;` or the CommonJS `const { Pool } = require('pg');` pattern. Make sure your `package.json` has `"type": "module"` if you intend to use native ESM.