Registry / database / pg-sql2

pg-sql2

JSON →
library5.0.1jsnpmunverified

Generate safe Postgres-compliant SQL using ES6 tagged template literals. Current stable version is 5.0.1, requiring Node >=22. It prevents SQL injection by forcing all values through allowed APIs like sql.value() and sql.identifier(). Built by the Graphile team, it is fast, ships TypeScript types, and is designed for highly dynamic query building. Unlike pg-promise or knex, it uses template literals for composable, compile-time safe SQL construction.

npm install pg-sql2
INSTALL
IMPORT
SIG · PG-SQL2
P
pg-sql2
databasejavascriptv5.0.1
harness data pending
Install & Compatibility
Where this runs

No compatibility data collected yet for this library.

Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

default
import sql from 'pg-sql2'
const sql = require('pg-sql2')
ESM-only since v5; CJS require still works but using default with require() requires .default or use import syntax
sql.compile
import sql from 'pg-sql2'; sql.compile(...)
import { compile } from 'pg-sql2'
compile is not a named export; it's a method on the default export
sql.value
import sql from 'pg-sql2'; sql.value(42)
import { value } from 'pg-sql2'
value is a method on the default export, not a named export
sql.identifier
import sql from 'pg-sql2'; sql.identifier('table', 'column')
import { identifier } from 'pg-sql2'
identifier is a method on the default export

Shows safe dynamic SQL construction with tagged templates, identifiers, values, join, and compile.

import sql from 'pg-sql2'; const tableName = 'user'; const fields = ['name', 'age', 'height']; const sqlFields = sql.join( fields.map((fieldName) => sql.identifier(tableName, fieldName)), ', ', ); const sqlConditions = sql`created_at > NOW() - interval '3 years' and age > ${sql.value(22)}`; const innerQuery = sql`select ${sqlFields} from ${sql.identifier(tableName)} where ${sqlConditions}`; const sqlAlias = sql.identifier(Symbol()); const query = sql` with ${sqlAlias} as (${innerQuery}) select (select json_agg(row_to_json(${sqlAlias})) from ${sqlAlias}) as all_data, (select max(age) from ${sqlAlias}) as max_age `; const { text, values } = sql.compile(query); console.log(text); console.log(values); // [22]
Debug
Known issues
breakingIn v5, the package is ESM-only; Node <22 is no longer supported.
fix
Upgrade to Node >=22 and use import syntax; if CJS required, use dynamic import or stick with v4.
affects: >=5.0.0
deprecatedsql.json and sql.raw are deprecated and will be removed in a future version.
fix
Use sql.literal with trusted strings instead of sql.raw; for JSON, use sql.value with JSON.stringify.
affects: >=4.0.0
gotchasql.literal does not escape values; using it with untrusted data can lead to SQL injection.
fix
Always use sql.value for untrusted or sensitive data; only use sql.literal with trusted constants.
affects: >=1.0.0
breakingVersions prior to v4 exported a default tagged template function; now the default export is an object with methods like compile, value, etc.
fix
Update imports: import sql from 'pg-sql2' and use sql`...` as before, but now call sql.compile(query).
affects: <4.0.0
gotchaUsing a plain value inside a template literal (e.g., sql`select ${42}`) throws an error; all non-sql fragments must be wrapped with sql.value or sql.identifier.
fix
Always wrap raw values with sql.value() and identifiers with sql.identifier().
affects: >=1.0.0
gotchasql.join is for joining SQL fragments with a separator, not for SQL JOIN operations; the name is misleading.
fix
Use sql.join for lists of fragments separated by commas, AND, OR, etc. For SQL JOINs, build manually.
affects: >=1.0.0
Errors
Common errors & fixes
TypeError: sql is not a function
Using default import but package imported incorrectly (e.g., import { sql } from 'pg-sql2' or const sql = require('pg-sql2') without .default).
fix
Use import sql from 'pg-sql2' (ESM) or const { default: sql } = require('pg-sql2') (CJS).
Error: sql`...` can only contain sql fragments, got: number
Passing a raw JavaScript value directly inside sql`` without wrapping in sql.value().
fix
Wrap the value: sql`... ${sql.value(42)} ...`
Error: identifier must be a string or Symbol, found object
Passing an object (e.g., an array) to sql.identifier().
fix
sql.identifier expects string or Symbol arguments; for multiple parts, pass as separate args: sql.identifier('schema', 'table').
Cannot find module 'pg-sql2' or its corresponding type declarations.
Package not installed or TypeScript cannot resolve types.
fix
npm install pg-sql2; ensure tsconfig.json includes 'node' resolution and skipLibCheck is false if needed.
TypeError: sql.compile is not a function
Using an older version (v3 or earlier) where compile was not a method; also possible if default import is wrong.
fix
Upgrade to v4+ and use import sql from 'pg-sql2', then sql.compile(query).
Upgrade
Version history
5.0.1latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
2 hits · last 30 days
node
2
Resources