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.
JSON-native TypeScript ORM for Bun, Browsers, Edge, Node, Workers
計測したスター増加
- 24時間
- 履歴を収集中
- 7日間
- 履歴を収集中
- 15日間
- 履歴を収集中
- 1か月
- 履歴を収集中
期間ごとの純増数です。期間は重複しており、日別の値ではありません。未計測の値は空欄です。スター数は注目度の指標であり、品質の保証ではありません。
README.md
オリジナルJSON-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! ⭐
関連プロジェクトを探す
Asabeneh/30-Days-Of-Python
30 Days of Python プログラミングチャレンジは、Python プログラミング言語を 30 日で学ぶためのステップバイステップのガイドです。このチャレンジは 100 日以上かかることもあります。自分のペースで進めてください。こちらの動画も役立つかもしれません: https://www.youtube.com/channel/UC7PNRuno1rzYPb1xLa4yktw
78,560 スターgrafana/grafana
オープンで組み合わせ可能なオブザーバビリティおよびデータ可視化プラットフォームです。Prometheus、Loki、Elasticsearch、InfluxDB、Postgres など、複数のソースからメトリクス、ログ、トレースを可視化できます。
77,830 スターredis/redis
リアルタイムのデータ駆動型アプリケーションを構築する開発者にとって、Redis は最も選ばれ、最速で、機能が最も豊富なキャッシュ、データ構造サーバー、ドキュメントおよびベクトルクエリエンジンです。
77,395 スターapache/superset
Apache Superset は、データ可視化とデータ探索のためのプラットフォームです。
75,473 スター