
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
linkgress-orm
Advanced tools
A lightweight, type-safe ORM for PostgreSQL with LINQ-style queries and automatic type inference
A type-safe ORM for PostgreSQL and TypeScript with automatic type inference and powerful query capabilities.
LINQ-Inspired Query Syntax: The query API is designed to feel familiar to developers coming from C# LINQ, with chainable methods like select(), where(), orderBy(), and groupBy(). You also get magic SQL string interpolation for when you need raw SQL power without sacrificing type safety.
PostgreSQL-First Philosophy: While other ORMs aim high and try to support all platforms, Linkgress is built exclusively for PostgreSQL. This allows it to leverage PostgreSQL's advanced features to the maximum—particularly in how collections and aggregations are retrieved using CTEs, LATERAL joins, JSON aggregations, and native PostgreSQL optimizations.
DbColumn<T>, no decorators neededDbContext pattern with method chainingcount(), sum(), max(), min() return proper types.where().update() and .where().delete() with RETURNING supportpg and postgres npm packagesnpm install linkgress-orm postgres
See Installation Guide for detailed setup.
import { DbEntity, DbColumn } from 'linkgress-orm';
export class User extends DbEntity {
id!: DbColumn<number>;
username!: DbColumn<string>;
email!: DbColumn<string>;
posts?: Post[]; // Navigation property
}
export class Post extends DbEntity {
id!: DbColumn<number>;
title!: DbColumn<string>;
userId!: DbColumn<number>;
views!: DbColumn<number>;
user?: User; // Navigation property
}
import { DbContext, DbEntityTable, DbModelConfig, integer, varchar } from 'linkgress-orm';
export class AppDatabase extends DbContext {
get users(): DbEntityTable<User> {
return this.table(User);
}
get posts(): DbEntityTable<Post> {
return this.table(Post);
}
protected override setupModel(model: DbModelConfig): void {
model.entity(User, entity => {
entity.toTable('users');
entity.property(e => e.id).hasType(integer('id').primaryKey().generatedAlwaysAsIdentity({ name: 'users_id_seq' }));
entity.property(e => e.username).hasType(varchar('username', 100)).isRequired();
entity.property(e => e.email).hasType(varchar('email', 255)).isRequired();
entity.hasMany(e => e.posts, () => Post)
.withForeignKey(p => p.userId)
.withPrincipalKey(u => u.id);
});
model.entity(Post, entity => {
entity.toTable('posts');
entity.property(e => e.id).hasType(integer('id').primaryKey().generatedAlwaysAsIdentity({ name: 'posts_id_seq' }));
entity.property(e => e.title).hasType(varchar('title', 200)).isRequired();
entity.property(e => e.userId).hasType(integer('user_id')).isRequired();
entity.property(e => e.views).hasType(integer('views')).hasDefaultValue(0);
entity.hasOne(e => e.user, () => User)
.withForeignKey(p => p.userId)
.withPrincipalKey(u => u.id);
});
}
}
import { eq, gt } from 'linkgress-orm';
import { PostgresClient } from 'linkgress-orm';
// Create a database client with connection pooling
const client = new PostgresClient('postgres://user:pass@localhost/db');
// Create a DbContext instance - reuse this across your application!
const db = new AppDatabase(client);
// Create schema
await db.ensureCreated();
// Insert
await db.users.insert({ username: 'alice', email: 'alice@example.com' });
// Query with filters
const activeUsers = await db.users
.where(u => eq(u.username, 'alice'))
.toList();
// Nested collection query with aggregations
const usersWithStats = await db.users
.select(u => ({
username: u.username,
postCount: u.posts.count(), // Automatic type inference - no casting!
maxViews: u.posts.max(p => p.views), // Returns number | null
posts: u.posts
.select(p => ({ title: p.title, views: p.views }))
.where(p => gt(p.views, 10))
.toList('posts'),
}))
.toList();
// Fluent update with RETURNING
const updatedUsers = await db.users
.where(u => eq(u.username, 'alice'))
.update({ email: 'alice.new@example.com' })
.returning(u => ({ id: u.id, email: u.email }));
// Fluent delete
await db.users
.where(u => eq(u.username, 'old_user'))
.delete();
// Note: Only call dispose() when shutting down your application
// For long-running apps (servers), keep the db instance alive
// and dispose on process exit (see Connection Lifecycle docs)
Result is fully typed:
Array<{
username: string;
postCount: number;
maxViews: number | null;
posts: Array<{ title: string; views: number }>;
}>
pg and postgres, connection pooling, and lifecycle managementContributions are welcome! Please see CONTRIBUTING.md for guidelines.
This project is licensed under the MIT License - see the LICENSE file for details.
Crafted with ❤️ for developers who love type safety and clean APIs.
FAQs
A lightweight, type-safe ORM for PostgreSQL with LINQ-style queries and automatic type inference
We found that linkgress-orm demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.