Skip to content

Quick Start

UQL is a type-safe TypeScript ORM whose queries are plain JSON, so the same query works on the server, in the browser, micro-services, and over the network.


Install the core and your preferred driver:

Terminal window
npm install uql-orm pg # or mysql2, better-sqlite3, mongodb, etc.

Here is a complete example of defining an entity, setting up a pool, and running a query.

entities.ts
import { v7 as uuidv7 } from 'uuid';
import { Entity, Id, Field } from 'uql-orm';
@Entity()
export class User {
@Id({ type: 'uuid', onInsert: uuidv7 })
id?: string;
@Field({ type: String, unique: true })
email?: string;
@Field({ type: String })
name?: string;
}
// uql.config.ts
import type { Config } from 'uql-orm';
import { PgQuerierPool } from 'uql-orm/postgres';
import { User } from './entities.js';
const pool = new PgQuerierPool({
host: 'localhost',
user: 'postgres',
password: 'password',
database: 'uql_app'
});
export default { pool, entities: [User] } satisfies Config;
export { pool };
// app.ts
import { pool } from './uql.config.js';
import { User } from './entities.js';
// A single operation goes straight on the pool: it acquires a connection, runs, and releases it.
await pool.insertMany(User, [
{ email: 'ada@uql-orm.dev', name: 'Ada' },
{ email: 'alan@uql-orm.dev', name: 'Alan' },
{ email: 'grace@example.com', name: 'Grace' },
]);
// Same for reads.
const users = await pool.findMany(User, {
$select: { id: true, name: true },
$where: { email: { $endsWith: '@uql-orm.dev' } },
$limit: 10,
});
console.log(users); // -> Ada and Alan; Grace's email doesn't match

Every operation lives on both the pool and the querier. A pool call is one unit of work on its own connection; pool.withQuerier (or pool.transaction when it must be all-or-nothing) pins one connection across several. See pool vs. querier.