High-performance, lightweight, and type-safe SQL query builder for Node.js
npm install zippydbLightweight, type-safe SQL Query Builder for Node.js + PostgreSQL.
``bash`
npm install zippydb
`typescript
import { Builder, PostgresDriver } from "zippydb";
interface User {
id: number;
name: string;
email: string;
age?: number;
}
const db = new Builder(
new PostgresDriver({
host: "localhost",
user: "postgres",
password: "password",
database: "mydb",
port: 5432,
}),
);
// Ready to use!
const users = await db.table
`
`typescript
// All records
await db.table
// First record
await db.table
// With condition
await db.table
// Multiple conditions
await db
.table
.where("age", ">=", 21)
.where("status", "=", "active")
.get();
// Order & limit
await db.table
// Pagination
await db.table
// Count
await db.table
// Select specific columns
await db.table
// Distinct
await db.table
// Group by
await db.table
`
`typescript
// Single record
await db.table
name: "John",
email: "john@example.com",
age: 30,
});
// Multiple records
await db.table
{ name: "User 1", email: "user1@example.com" },
{ name: "User 2", email: "user2@example.com" },
]);
`
`typescript
// Single record
await db
.table
.where("id", "=", 1)
.update({ name: "Jane", age: 31 });
// Multiple records
await db
.table
.where("status", "=", "inactive")
.update({ status: "active" });
`
`typescript
// Single record
await db.table
// Multiple records
await db.table
`
`typescript`
.where('age', '=', 18) // Equal
.where('age', '!=', 18) // Not equal
.where('age', '>', 18) // Greater than
.where('age', '>=', 18) // Greater than or equal
.where('age', '<', 65) // Less than
.where('age', '<=', 65) // Less than or equal
.where('name', 'LIKE', '%john%') // Pattern matching
`typescript`
const users = await db
.table
.where("age", ">=", 21)
.where("status", "=", "active")
.orderBy("created_at", "desc")
.limit(10)
.offset(0)
.select("id", "name", "email")
.get();
`typescript
async function main() {
// CREATE
const user = await db.table
name: "Alice",
email: "alice@example.com",
age: 28,
});
// READ
const found = await db
.table
.where("email", "=", "alice@example.com")
.first();
// UPDATE
await db.table
// LIST
const all = await db.table
// DELETE
await db.table
}
main();
`
`typescript
async function paginate(page: number, perPage: number = 10) {
const offset = (page - 1) * perPage;
const [data, total] = await Promise.all([
db.table
db.table
]);
return {
data,
total,
page,
perPage,
pages: Math.ceil(total / perPage),
};
}
`
`typescript
import express from 'express';
import { Builder, PostgresDriver } from 'zippydb';
const app = express();
const db = new Builder(new PostgresDriver({...}));
app.get('/users', async (req, res) => {
const users = await db.table
res.json(users);
});
app.post('/users', async (req, res) => {
const user = await db.table
res.status(201).json(user);
});
app.listen(3000);
`
`typescript
import { Injectable } from '@nestjs/common';
import { Builder, PostgresDriver } from 'zippydb';
@Injectable()
export class UserService {
private db = new Builder(new PostgresDriver({...}));
async findAll(): Promise
return this.db.table
}
async findById(id: number): Promise
return this.db.table
.where('id', '=', id)
.first();
}
async create(data: Partial
return this.db.table
}
}
`
`typescript`
const driver = new PostgresDriver({
host: "localhost",
port: 5432,
database: "mydb",
user: "postgres",
password: "password",
ssl: false,
connectionTimeoutMillis: 0,
idleTimeoutMillis: 30000,
max: 20, // Max pool connections
});
ZippyDB uses parameterized queries by default - SQL injection safe.
`typescript`
// ✅ SAFE - Automatically parameterized
const user = await db.table
1. Create indexes on frequently queried columns:
`sql`
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_status ON users(status);
2. Limit results to reduce memory:
`typescript`
.limit(100)
3. Select only needed columns:
`typescript`
.select('id', 'name')
4. Connection pooling is enabled by default
`typescript
describe('User Service', () => {
let db: Builder;
beforeAll(() => {
db = new Builder(new PostgresDriver({...}));
});
it('should fetch all users', async () => {
const users = await db.table
expect(Array.isArray(users)).toBe(true);
});
it('should find user by email', async () => {
const user = await db.table
.where('email', '=', 'test@example.com')
.first();
expect(user?.email).toBe('test@example.com');
});
});
`
Connection timeout?
`typescript`
const driver = new PostgresDriver({
connectionTimeoutMillis: 30000,
...config,
});
Type errors?
Make sure your interface matches the table structure:
`typescript`
interface User {
id: number;
email: string; // Must exist
}
Slow queries?
- Add indexes to filtered columns
- Use .limit() to reduce results.select()` instead of SELECT \*
- Use
✅ Type-safe with TypeScript
✅ Fluent chainable API
✅ SQL injection protection
✅ Connection pooling
✅ Minimal dependencies
✅ Production ready
- [x] PostgreSQL support
- [ ] MySQL driver
- [ ] SQLite driver
- [ ] Migrations
- [ ] Joins & relationships
- [ ] Transactions
- [ ] Query caching
Email: ixlosbekerkinov.work@gmail.com
---
Star ⭐ on GitHub