rogerpadilla/uql has 132 GitHub stars and 5 forks. Star changes are not measured yet. Last checked 2026-11-12 10:06 UTC. Last push 2026-11-11.
Comment ces chiffres sont mesurés
JSON-native TypeScript ORM for Bun, Browsers, Edge, Node, Workers
Progression mesurée des étoiles
- in 24h
- Historique en cours
- in 7 days
- Historique en cours
- in 15 days
- Historique en cours
- in 1 month
- Historique en cours
Variations nettes sur des périodes qui se chevauchent, pas des totaux quotidiens. Les mesures absentes restent vides. Les étoiles indiquent l’intérêt, pas la qualité.
README.md
OriginalJSON-native ORM for TypeScript
UQL handles SQL databases and MongoDB with plain & type-safe JSON-syntax.
Website · Quick Start · Benchmark · Compare ORMs · Blog
npm install uql-orm pg
That is the whole install, pg swapped for your database's driver: mysql2, mariadb, better-sqlite3, mongodb, @tursodatabase/serverless or @libsql/client (setup). No compiler flags and no reflect-metadata.
The compiler catches each of those, with no codegen: the entity classes are the schema. Try the editor on the home page.
How it fits together
1. The entities are the schema
// entities.ts
import { Entity, f, Field, ManyToOne, OneToMany } from 'uql-orm';
@Entity()
export class User {
@Field(f.number().autoIncrement())
id?: number;
@Field(f.string().unique())
email!: string;
@OneToMany(() => Post, { mappedBy: (post) => post.author })
posts?: Post[];
}
@Entity()
export class Post {
@Field(f.number().autoIncrement())
id?: number;
@Field(f.string())
title!: string;
@Field(f.number().nullable())
likes?: number | null;
@Field(f.references(() => User).nullable())
authorId?: number | null;
@ManyToOne(() => User, { references: (post) => post.authorId })
author?: User;
}
Or declare one as data, its row type derived:
import { defineEntity, f } from 'uql-orm';
export const Post = defineEntity({
name: 'Post',
fields: {
id: f.number().autoIncrement(),
title: f.string(),
likes: f.number().nullable(),
authorId: f.number().nullable(),
},
}).relations((rel) => ({
author: () => rel.manyToOne(User, { references: (post) => post.authorId }),
}));
// One name for the entity and its rows, as a class has: a function takes `post: Post`, and hovers and errors print `Post`.
export interface Post extends InstanceType<typeof Post> {}
2. A pool, and the migrations it drives
// uql.config.ts
import type { Config } from 'uql-orm';
import { PgQuerierPool } from 'uql-orm/postgres';
import { Post, User } from './entities.js';
export const pool = new PgQuerierPool({ connectionString: process.env.DATABASE_URL });
export default { pool, entities: [User, Post] } satisfies Config;
npm i -D tsx # Node only: the CLI loads uql.config.ts through it
npx uql-migrate generate:entities initial # writes the diff against the database, to review
npx uql-migrate up # applies it
3. Query
import { Post } from './entities.js';
import { pool } from './uql.config.js';
const posts = await pool.findMany(Post, {
$select: { title: true },
$populate: { author: { $select: { email: true } } },
$where: { likes: { $gte: 10 } },
$sort: { likes: 'desc' },
$limit: 10,
});
// SELECT "Post"."title", "author"."id" "author.id", "author"."email" "author.email"
// FROM "Post" LEFT JOIN "User" "author" ON "author"."id" = "Post"."authorId"
// WHERE "Post"."likes" >= $1 ORDER BY "Post"."likes" DESC LIMIT 10
The result is typed to what the query selected: posts[0].author?.email compiles, posts[0].likes does not.
The same queries run from the browser too: serve them over HTTP, tRPC or oRPC, each field exposed as you declare, scoped to the signed-in user by filters no $where can widen.
Why UQL?
- One API, everywhere it runs. PostgreSQL, PGlite, CockroachDB, MySQL, MariaDB, MSSQL, SQLite, Turso, libSQL, Neon, Cloudflare D1, Bun's native SQL, and even MongoDB. The same code on Node 22.18+, Bun, Cloudflare Workers, AWS Lambda and Vercel, and the browser, with no native binaries on the
fetch-based drivers. - Type-safe to the leaf, nothing to generate. Every key is checked against your entity, down into populated relations and JSON/JSONB dot-paths, so
$likeon a numeric column is a compile error. No.prismafile, no generated client. - Decorators or plain data, your call. An entity is a class with standard TC39 decorators, or plain data via
defineEntity, its row type derived. Both are typed the same, mix in one project, and need no compiler flags orreflect-metadata. - Light. Zero runtime dependencies and every dialect in one package, yet
uql-orm/postgresis about 49 kB gzipped. See what we deleted to get there. - The hard things are built in. Semantic and vector search, multi-tenant filters you cannot bypass by accident, soft-delete with restore, streaming, and drift checks that catch a database that no longer matches.
- SQL when you need it.
sql()fits anywhere a value or a field goes, computed fields are SQL you can filter and sort on, and a migration can be plain SQL. - The fastest ORM. On a full PostgreSQL round trip it adds the least over hand-written driver code of any ORM in our open-source benchmark, on Bun and Node alike. The same benchmark scores the types by compiling ordinary mistakes in each ORM's API: UQL is the only one that catches them all.
Get started
Follow the Quick Start, or switch from Prisma, Drizzle, TypeORM or MikroORM. The examples are runnable apps on Node, Bun, Next.js and Cloudflare D1, each checked in CI.
Using a coding agent? The package ships a skill for it, and every docs page is Markdown: set it up.
Release notes live in CHANGELOG.md, and the build order for what comes next in architecture/roadmap.md.
Enjoy UQL! ⭐
Explorer des projets similaires
Asabeneh/30-Days-Of-Python
Le défi de programmation 30 Days of Python est un guide pas à pas pour apprendre le langage de programmation Python en 30 jours. Ce défi peut prendre plus de 100 jours. Avancez à votre rythme. Ces vidéos peuvent aussi vous aider : https://www.youtube.com/channel/UC7PNRuno1rzYPb1xLa4yktw
78,618 étoilesgrafana/grafana
Plateforme ouverte et composable d’observabilité et de visualisation de données. Visualise les métriques, les journaux et les traces issus de plusieurs sources, comme Prometheus, Loki, Elasticsearch, InfluxDB, Postgres et bien d’autres.
77,859 étoilesredis/redis
Pour les développeurs qui créent des applications en temps réel pilotées par les données, Redis est le cache, le serveur de structures de données et le moteur de requêtes documentaires et vectorielles préféré, le plus rapide et le plus riche en fonctionnalités.
77,472 étoilesapache/superset
Apache Superset est une plateforme de visualisation et d'exploration de données.
75,495 étoiles