A lightweight Node.js utility for working with PostgreSQL without the boilerplate.
psqljs wraps pg (Pool) with simple, reusable helpers for querying, CRUD, and table management β so you don't have to rewrite connection and query logic for every project.
β οΈ Beta: psqljs is currently under development. The API may change and is not yet recommended for production.
- π Zero-config pool via
dotenv+pg(db.js:7) - π¬ Raw SQL via
Query(sql, values)with parameterized values - π Select helpers:
findAll,findOne,findMany - βοΈ CRUD helpers:
Insert,Update,Remove(withRETURNING *) - ποΈ Table helpers:
CreateTable,DeleteTable,TableExists,GetTables,GetColumns - π¦ ESM-first (
package.json:13β"type": "module")
npm install psqljs
# not published yet β for local development:
git clone https://github.com/your-org/psqljs.git
cd psqljs
npm installRequirements: Node.js >= 18, PostgreSQL, pg@^8.23.0, dotenv@^17.4.2.
psqljs reads connection info from environment variables via dotenv in db.js:1-13.
Create a .env in the project root:
host=localhost
port=5432
database=mydb
user=postgres
password=your_passwordThese map directly to new Pool({ host, port, database, user, password }) in db.js:7-13. db.js:15-16 exports both named pool and default for advanced use.
.envis gitignored (.gitignore:2).
import psql from "./Func/Main.js";
// 1. Test connection
if (await psql.testConnection()) {
console.log("Connection successful");
}
// 2. Raw query
const rows = await psql.Query("SELECT * FROM users WHERE id = $1", [1]);
// 3. CRUD helpers
const user = await psql.Insert("users", { name: "Ada", email: "ada@example.com" });
const found = await psql.findOne("users", "email", "ada@example.com");
const updated = await psql.Update("users", { name: "Ada Lovelace" }, "id", user.id);
const removed = await psql.Remove("users", "id", user.id);Or import helpers directly:
import { Query } from "./Func/Query.js";
import { Insert } from "./Func/Insert.js";
import { CreateTable } from "./Func/Table.js";All helpers are re-exported from Func/Main.js:19-36.
Execute raw parameterized SQL. Returns result.rows.
import { Query } from "./Func/Query.js";
await Query("SELECT * FROM users WHERE id = $1", [1]);
await Query("SELECT 1"); // -> [{ "?column?": 1 }]Runs SELECT 1 via Query. Returns true if rows returned, false on error.
import { testConnection } from "./Func/Connection.js";
await testConnection(); // true | falseNote:
testConnectioncallspool.end()infinally(Func/Connection.js:14). After calling it, the pool is closed and subsequent queries will fail unless you recreate the pool. Avoid using it in long-lived servers β use it for CLI checks /index.js:4.
| Function | Signature | Description | Returns |
|---|---|---|---|
findAll |
findAll(table) |
SELECT * FROM table |
rows[] |
findOne |
findOne(table, column, value) |
SELECT ... WHERE column = $1 LIMIT 1 |
row | null |
findMany |
findMany(table, column, value) |
SELECT ... WHERE column = $1 |
rows[] |
await findAll("users");
await findOne("users", "id", 42); // null if not found
await findMany("users", "role", "admin");Table/column names are interpolated (
Func/Select.js:4,11,20). Pass trusted values only β they are not parameterized.
Inserts one row. data is an object { column: value }. Builds $1, $2... placeholders and returns RETURNING *.
await Insert("users", { name: "Grace", email: "grace@example.com" });
// -> { id: 1, name: "Grace", email: "grace@example.com", ... }Updates rows matching whereColumn = whereValue. data is the SET object. Returns first updated row or null.
await Update("users", { name: "Grace Hopper", role: "admin" }, "id", 1);Deletes rows matching column = $1. Returns deleted row or null.
await Remove("users", "id", 1);| Function | Signature | Description |
|---|---|---|
CreateTable |
CreateTable(table, columns) |
CREATE TABLE "table" (...) β columns is { name: "TEXT NOT NULL", age: "INT" } (Func/Table.js:3) |
DeleteTable |
DeleteTable(table) |
DROP TABLE "table" (Func/Table.js:15) |
TableExists |
TableExists(table) |
Checks information_schema.tables (Func/Table.js:19), returns boolean |
GetTables |
GetTables() |
Lists BASE TABLEs in public schema (Func/Table.js:31) |
GetColumns |
GetColumns(table) |
Lists column_name, data_type, is_nullable, column_default for table (Func/Table.js:41) |
await CreateTable("users", {
id: "SERIAL PRIMARY KEY",
name: "TEXT NOT NULL",
email: "TEXT UNIQUE NOT NULL",
created_at: "TIMESTAMP DEFAULT NOW()"
});
await TableExists("users"); // true
await GetTables(); // [{ table_name: "users" }, ...]
await GetColumns("users"); // [{ column_name: "id", data_type: "integer", ... }]
await DeleteTable("users");psqljs/
βββ db.js # pg Pool setup from .env
βββ index.js # Demo: testConnection()
βββ Func/
β βββ Main.js # Default export aggregating all helpers
β βββ Connection.js # testConnection()
β βββ Query.js # Query()
β βββ Select.js # findAll / findOne / findMany
β βββ Insert.js # Insert()
β βββ Update.js # Update()
β βββ Delete.js # Remove()
β βββ Table.js # CreateTable / DeleteTable / TableExists / GetTables / GetColumns
βββ package.json # ESM, pg, dotenv
βββ .env # host, port, database, user, password (gitignored)
db.jscreates a singletonPoolfrom env vars.- Every helper imports
pooland callspool.query(...). Queryis the primitive β all other helpers build on top of it orpooldirectly.- See
index.js:1-11for a minimal connection check.
π§ Beta / Early Development β API is stabilizing.
- Raw query + select helpers
- Insert / Update / Delete
- Table management
- Transactions /
BEGIN/COMMIThelper - Input validation & safer identifier escaping
- Connection retry / pool config exposure
- Tests & CI
- npm publish
MIT β see package.json:11 (currently ISC, will be aligned to MIT).
PRs welcome. Please keep helpers parameterized where possible and add JSDoc for new functions.