libpg-query-node
The real PostgreSQL parser, compiled to WebAssembly, for parsing SQL into ASTs in any JavaScript runtime.
Repository Health
Technical Analysis
libpg-query is a WebAssembly build of PostgreSQL’s own SQL parser (libpg_query), exposing the exact grammar and lexer the real Postgres server uses inside a Node.js- or browser-compatible JavaScript package. Rather than reimplementing SQL parsing with a hand-written grammar, it compiles the actual Postgres C parser to WASM, so the resulting abstract syntax tree matches what Postgres itself would produce, including edge cases, dialect quirks, and version-specific syntax.
The package ships as multiple npm dist-tags (pg13 through pg18), each built against a specific PostgreSQL major version’s grammar, letting consumers pin the parser to the SQL dialect their database actually runs. It exposes a minimal parse/parseSync API that returns a JSON parse tree, with structured SqlError details (cursor position, source file, line number) instead of an opaque parse failure, and requires no native compilation or node-gyp step on install.
What You Get
- Full PostgreSQL grammar parsing via the real Postgres C parser compiled to WASM
- Version-pinned builds (PG13 through PG18) selectable via npm dist-tags
- Async
parse()and synchronousparseSync()entry points with automatic or explicit WASM initialization - Structured
SqlErrorobjects carrying cursor position, filename, line number, and context for parse failures - Zero native runtime dependencies — no node-gyp, no platform-specific binaries to build
Common Use Cases
- Building SQL linters and static-analysis tools that validate queries before execution
- Powering query builders and ORMs (e.g. pgsql-parser) that need to construct or introspect SQL programmatically
- Parsing DDL/DML for migration and schema-diffing tooling
- Feeding SQL editors and IDE plugins with precise syntax-error positions while typing
Under The Hood
Architecture
The repo is a pnpm monorepo where each supported PostgreSQL major version (13 through 18) lives in its own versions/<N> package, each with a generated src/index.ts (templated from the shared templates/ directory and synced via copy:templates) that wraps a thin C shim (src/wasm_wrapper.c) compiled to WASM via a per-version Makefile invoking Emscripten. The JS layer marshals strings across the WASM boundary manually (stringToPtr/ptrToString, _malloc/_free) and reads the PgQueryParseResult/PgQueryError C structs directly by pointer offset before JSON-parsing the returned parse tree. There is effectively one layer of indirection: JS API surface directly reflects the WASM export surface, so any change to wasm_wrapper.c or the underlying libpg_query fork propagates straight through to the public parse/parseSync functions.
Tech Stack
TypeScript for the public API, C for the WASM wrapper around a constructive-io/libpg_query fork of the upstream pganalyze/libpg_query project, Emscripten (via a Dockerized emsdk image) for the C-to-WASM build, and pnpm workspaces to manage the six version packages plus companion @pgsql/types, @pgsql/enums, and @pgsql/parser packages in the same repo. The published libpg-query package (currently dist-tag latest = PG17, 17.7.4) depends only on @pgsql/types at runtime.
Code Quality
Each version package has its own test suite using Node’s built-in node:test runner, covering sync/async parsing, multi-statement queries, and structured parse-error shapes (parsing.test.js, errors.test.js); the PG18 package additionally tests fingerprint, normalize, plpgsql, and scan since it ships the full API. CI runs a build+test matrix across all six PG versions on GitHub Actions, with a documented Docker-based WASM build path. Errors are explicit and typed via a custom SqlError class rather than swallowed, and the public API is fully typed. No dedicated lint config was found at the repo root.
API Design
The public surface is intentionally tiny: parse() (async, auto-initializing) and parseSync() (requires an explicit loadModule() call first), plus a formatSqlError() helper for human-readable diagnostics. This removes the most common footgun with WASM modules — forgetting to await initialization — for the recommended async path, while still offering a synchronous escape hatch for hot loops. Multi-version support via npm dist-tags (pg13-pg18) is a deliberate DX choice: consumers get exact-version grammar matching without needing to depend on a differently-named package per PostgreSQL version.
Used by 3 apps in this directory
Infisical
Security · Devops
The open-source platform for secrets, certificates, privileged access, and AI agent security — all in one self-hostable system.
InsForge
Developer Tools · Databases
The all-in-one, open-source backend platform purpose-built for AI coding agents — giving your agent database, auth, storage, edge functions, a model gateway, and compute to ship full-stack apps end-to-end.
Supabase
Developer Tools · Databases · Search
The open-source Postgres development platform that replaces Firebase with authentication, real-time APIs, edge functions, storage, and vector embeddings — all built on PostgreSQL.