pg-hstore

Serializes and parses PostgreSQL hstore key-value strings to and from plain JavaScript objects.

Library
npm
v2.3.4
108stars
MIT License

Repository Health

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

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
44/100Fair
Architecture58
Code Quality58
Innovation35
Learning Curve25

pg-hstore is a small Node.js utility for converting between JavaScript objects and PostgreSQL’s hstore text format — the "key"=>"value" string representation Postgres uses for its hstore key-value column type. It exposes two functions, stringify and parse, that handle the escaping rules for quotes, backslashes, and null values required by the hstore wire format, so application code can pass plain objects to Postgres and get plain objects back without writing custom regex or escaping logic.

The library underpins hstore support in Sequelize, one of the most widely used Node.js ORMs, where it converts model attribute values to and from the hstore column type transparently. It’s a lightweight, single-purpose dependency rather than a general-purpose ORM or query builder — its only job is the serialize/deserialize round trip for hstore data.

What You Get

  • stringify() - Converts a plain JavaScript object into a hstore-formatted string, quoting keys and values and encoding null as the hstore NULL literal
  • parse() - Converts a hstore-formatted string back into a plain JavaScript object, unescaping quotes and backslashes along the way
  • Optional sanitization - A sanitize option escapes single quotes, backslashes, and double quotes in input values before stringifying, per the Postgres lexical rules for hstore literals
  • Callback and return-value API - Both stringify and parse work as synchronous return values or accept an optional callback, fitting either style of calling code

Common Use Cases

  • Sequelize hstore columns - Sequelize uses pg-hstore internally to serialize and deserialize values for its HSTORE data type
  • Direct node-postgres queries - Applications querying hstore columns with node-postgres can use pg-hstore to convert results into usable JS objects
  • Migrating key-value data into Postgres - Converting arbitrary JSON-like config or metadata objects into the hstore format for storage
  • Round-tripping hstore text - Any tool that needs to read or write raw hstore strings without going through a full ORM

Under The Hood

Architecture The entire module is a single file, lib/index.js (under 80 lines), wrapped in an IIFE and exporting one factory function that accepts a { sanitize } option and returns an object with stringify and parse closures. There are no internal layers, classes, or abstractions to trace — stringify maps over Object.keys(data) and joins quoted "key"=>"value" pairs, while parse tokenizes the input with a single regular expression that matches quoted segments or the NULL literal, then unescapes each token. The design is appropriately minimal for its narrow scope: changing behavior means editing one of these two functions directly, with no dependency-injection points or configuration beyond the single sanitize flag.

Tech Stack The module targets plain Node.js (engines: >= 0.8.x in package.json, reflecting its age) and has exactly one runtime dependency, underscore (^1.13.1), used solely for _.defaults to merge the options object. There is no build step, no TypeScript, and no bundler — it ships as plain CommonJS via module.exports. Dev dependencies are mocha (^2.1.0) and should (^4.4.2) for BDD-style testing. It has no direct dependency on pg or node-postgres itself, despite being designed to pair with them.

Code Quality Tests live under test/ (index.js, parse.js, stringify.js) using Mocha with should.js assertions, and cover a reasonably thorough set of behavioral cases for the module’s narrow surface: quoted values, null handling, embedded commas and newlines, escaped quotes and backslashes, and both sanitized and unsanitized round trips. There is no TypeScript or other type safety, no modern linter configuration beyond a legacy .jshintrc, and CI is limited to a one-line .travis.yml referencing a now largely defunct CI provider. Error handling is minimal — parse simply returns an empty object when the regex finds no matches rather than raising on malformed input. Naming is terse but internally consistent, and the repository has seen no commits since mid-2021.

API Design The public surface is deliberately tiny: instantiate via require('pg-hstore')(options) and call stringify/parse. Naming maps directly onto what each function does, and both accept an optional callback in addition to returning a value directly, which lets callers use either a synchronous or callback style with no extra ceremony. Getting started requires no configuration — the default options work for the common case — though the one non-obvious option (sanitize) is only documented implicitly through its test coverage rather than in the README.

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