node-pg-types

Converts raw PostgreSQL wire-protocol values into JavaScript types by OID, powering node-postgres query result parsing.

Library
npm
v4.1.0
303stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
38/100Needs Attention
Development Activity0
Maintenance0
Community72
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
66/100Good
Architecture74
Code Quality76
Innovation68
Learning Curve45

pg-types is the type-conversion layer that node-postgres (pg) uses internally to turn raw values coming back from a PostgreSQL server into native JavaScript types. PostgreSQL returns every column value as text, or as a compact binary payload when binary mode is requested, tagged with a type OID; pg-types maps that OID to a parser function and produces the JS value an application actually receives, covering numbers, booleans, dates, arrays, ranges, and JSON.

The library ships a large table of built-in OID-to-parser mappings for both PostgreSQL’s text and binary wire formats, and exposes getTypeParser/setTypeParser so applications can override how any given type (by OID or by name via the generated builtins map) is parsed, for example returning int8/numeric as strings to avoid JavaScript number overflow, or routing timestamps through a different date library.

What You Get

  • Built-in parsers for PostgreSQL’s core scalar types (int2/int4/int8, float4/float8, bool, bytea, json/jsonb, timestamps, UUID) in both text and binary wire formats
  • Array and range/multirange parsing (e.g. _int4, int4range, daterange) that recursively parses each element with the matching sub-parser
  • A generated builtins map of every stable PostgreSQL core type name to its OID, kept current via a Docker Compose-based generator that queries live PostgreSQL 11/14 instances
  • getTypeParser/setTypeParser API so consuming code, typically node-postgres itself, can register custom parsers per OID and format without forking the library
  • A small dependency footprint made up of focused sibling packages (pg-int8, pg-numeric, postgres-array, postgres-date, postgres-interval, postgres-range, postgres-bytea), each handling one PostgreSQL data-type family

Common Use Cases

  • Used automatically by node-postgres/pg to decode every query result row without any explicit setup
  • Overriding int8/numeric parsing to receive JS numbers instead of strings when values are guaranteed to stay within the safe integer range
  • Registering a custom parser for timestamp/timestamptz to hand back a moment/dayjs/luxon object instead of a native Date
  • Any Postgres client library or ORM adapter that needs OID-aware conversion of raw wire-protocol values into JS types without reimplementing PostgreSQL’s type catalog

Under The Hood

Architecture pg-types is a small, flat module: index.js exposes getTypeParser/setTypeParser backed by two in-memory lookup tables (typeParsers.text and typeParsers.binary) that are populated at require-time via an init(register) callback pattern in lib/textParsers.js and lib/binaryParsers.js, decoupling parser registration from the public API. lib/builtins.js supplies a generated OID-to-name map consumed by both the JS entry point and the hand-written index.d.ts type declarations. There is no dependency injection, no async data flow, and no layering beyond “lookup table in, parser function out” - changing the core abstraction (the oid/format keyed table) would require touching both parser files and any downstream consumer, chiefly node-postgres, that relies on its shape.

Tech Stack The implementation is plain, framework-free JavaScript with hand-authored TypeScript ambient declarations (index.d.ts, verified by tsd rather than compiled). Runtime dependencies are a family of tiny, single-purpose sibling packages (pg-int8, pg-numeric, postgres-array, postgres-bytea, postgres-date, postgres-interval, postgres-range) each owning one PostgreSQL data-type family. A separate generator/ directory uses Docker Compose to spin up real PostgreSQL 11 and 14 containers, query pg_type, and regenerate lib/builtins.js, keeping the OID table sourced from an actual server rather than hand-maintained. Testing uses tape/tap-spec, linting uses standard, and coverage is measured with nyc/codecov.

Code Quality test/index.js iterates a large table-driven fixture file (test/types.js) that exercises both the text and binary parser for every registered OID, plus targeted edge-case tests (binary array overflow handling, oid-must-be-integer validation). CI (.github/workflows/ci.yml) runs the linter, the test suite across five Node versions (12 through 20), the tsd type-definition tests, and a dedicated job that regenerates builtins.js and fails the build on any diff, guarding against the generated table silently drifting from the docs. Error handling is minimal by design, limited to explicit validation in setTypeParser; there is no LICENSE file or CONTRIBUTING guide in the repository despite package.json declaring an MIT license.

API Design The public surface is deliberately tiny: two functions (getTypeParser, setTypeParser) plus a generated builtins name-to-OID map, requiring zero configuration for the default behavior since node-postgres wires it up automatically. Overriding a parser is a single setTypeParser call keyed by OID or builtins name, and the shipped index.d.ts plus tsd-driven index.test-d.ts give consumers strong editor autocomplete and type-checked overrides despite the implementation itself being untyped JavaScript.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search