{"id":43644,"library":"possu","title":"Possu – node-postgres companion","description":"A small companion library for node-postgres that reduces boilerplate by using tagged template literals for SQL queries, with automatic result row/column unwrapping. Current stable version 3.0.0, released periodically. Key differentiators: Promise-based API, runtime SQL injection prevention via tagged templates, built-in transaction and savepoint handling with retry on serialization failures/deadlocks, first-class TypeScript support, and not a framework – works directly with pg.Pool/pg.PoolClient.","status":"active","version":"3.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/sluukkonen/possu","tags":["javascript","pg","postgres","postgresql","node-postgres","promise","tagged","template","strings","typescript"],"install":[{"cmd":"npm install possu","lang":"bash","label":"npm"},{"cmd":"yarn add possu","lang":"bash","label":"yarn"},{"cmd":"pnpm add possu","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency – possu is built on and expects node-postgres Pool/Client instances.","package":"pg","optional":false}],"imports":[{"note":"ESM-only since v3. Use default import for CommonJS: const possu = require('possu'); const { sql } = possu;","wrong":"const sql = require('possu').sql","symbol":"sql","correct":"import { sql } from 'possu'"},{"note":"query is a named export, not default.","wrong":"import query from 'possu'","symbol":"query","correct":"import { query } from 'possu'"},{"note":"Named export. CommonJS usage: const { withTransaction } = require('possu');","wrong":"const withTransaction = require('possu').withTransaction","symbol":"withTransaction","correct":"import { withTransaction } from 'possu'"},{"note":"Throws if no rows returned.","wrong":null,"symbol":"queryOne","correct":"import { queryOne } from 'possu'"},{"note":"Returns row or undefined.","wrong":null,"symbol":"queryMaybeOne","correct":"import { queryMaybeOne } from 'possu'"}],"quickstart":{"code":"import { Pool } from 'pg';\nimport { query, queryMaybeOne, sql } from 'possu';\n\nconst pool = new Pool({ connectionString: process.env.DATABASE_URL ?? '' });\n\nasync function getUser(id: number) {\n  const client = await pool.connect();\n  try {\n    const user = await queryMaybeOne(client, sql`SELECT * FROM users WHERE id = ${id}`);\n    console.log(user?.name ?? 'Not found');\n  } finally {\n    client.release();\n  }\n}\n\ngetUser(1).catch(console.error);","lang":"typescript","description":"Shows a basic query selecting one row by id using tagged template literal and automatic unwrapping."},"warnings":[{"fix":"Use import syntax and set type: 'module' in package.json, or use dynamic import().","message":"possu v3 drops CommonJS support – only ESM imports work. require() will fail.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Use sql`SELECT * FROM users` instead of sql('SELECT * FROM users')","message":"The `sql` function no longer accepts string concatenation – must be used as a tagged template literal. Passing a plain string will throw at runtime.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Prefer sql`SELECT name FROM users` and let possu unwrap automatically.","message":"The `queryOne` function without specifying column name may be deprecated in future. Use explicit column selection in SQL.","severity":"deprecated","affected_versions":">=2.0.0"},{"fix":"Use for (const row of result) instead of for await (const row of result).","message":"Async generators (for-await-of) are not supported; query results are arrays, not iterables.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always combine nested sql calls as arguments to parent sql tag – not concatenated strings.","message":"Nested `sql` calls can lead to unexpected parameter numbering if not used carefully. Each `sql` tag creates independent numbered placeholders.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"search_vec":"'/pg.poolclient.':75 '3.0.0':33 'api':41 'automat':26 'base':40 'boilerpl':16 'built':50 'built-in':49 'class':63 'companion':5,8 'current':30 'differenti':37 'direct':71 'failures/deadlocks':60 'first':62 'first-class':61 'framework':69 'handl':55 'inject':44 'javascript':76 'key':36 'librari':9 'liter':21 'node':3,12,81 'node-postgr':2,11,80 'period':35 'pg':77 'pg.pool':74 'pg.pool/pg.poolclient.':73 'possu':1 'postgr':4,13,78,82 'postgresql':79 'prevent':45 'promis':39,83 'promise-bas':38 'queri':24 'reduc':15 'releas':34 'result':27 'retri':57 'row/column':28 'runtim':42 'savepoint':54 'serial':59 'small':7 'sql':23,43 'stabl':31 'string':86 'support':65 'tag':19,47,84 'templat':20,48,85 'transact':52 'typescript':64,87 'unwrap':29 'use':18 'version':32 'via':46 'work':70","created_at":"2026-06-05T17:00:47.556525+00:00","updated_at":"2026-06-05T17:00:47.556525+00:00","problems":[{"fix":"Use sql`...` syntax or import { sql } from 'possu'.","cause":"Using sql as a regular function instead of a tagged template literal, or importing incorrectly (named vs default).","error":"Error: sql is not a function"},{"fix":"Call query(poolClient, sql`...`) – possu expects a client/pool as first argument, not the pool's method.","cause":"Passing a PoolClient or Pool directly to query instead of using the pool's query method.","error":"TypeError: pool.query is not a function"},{"fix":"Install with npm install possu, and use import syntax. For older Node, use dynamic import or downgrade to v2.","cause":"Package not installed, or using CommonJS require with ESM-only package (v3+).","error":"Cannot find module 'possu'"},{"fix":"Wrap your SQL string with sql`...`.","cause":"Passing a raw string instead of a SqlQuery object to query/execute functions.","error":"Error: The query must be created with the sql tag"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/sluukkonen/possu","github":"https://github.com/sluukkonen/possu","docs":null,"changelog":null,"pypi":null,"npm":"possu","openapi_spec":null,"status_page":null,"smithery":null,"categories":["database"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-05","next_check":"2026-09-03","install_tag":null}}