> Every UQL docs page, as Markdown: https://uql-orm.dev/llms.txt
> The same docs over MCP: https://uql-orm.dev/mcp
> Before writing UQL code, read the skill: https://uql-orm.dev/.well-known/agent-skills/uql-orm/SKILL.md

# Zero dependencies: what we deleted

> uql-orm installs one package, 288 kB on the wire, no runtime dependencies, every dialect included. Here is what came out to get there: reflect-metadata, jiti, tslib, sqlstring, 369 sourcemaps, and the changelog.

Source: https://uql-orm.dev/blog/zero-dependencies

`npm i uql-orm` installs one package. No dependencies, every dialect included.

A month ago it had four mandatory packages, roughly 4 MBs unpacked; now it is 992 KB unpacked.

## One release, four dependencies gone

`0.21.0` did it in one pass: \~4.0 MB down to 992 KB, cold start from 16.9 ms to 8.9 ms. Four packages, one job each, none worth a dependency of its own.

`tslib` existed so TypeScript’s helper functions didn’t repeat across files. `"importHelpers": false` costs a few hundred bytes per file instead of a dependency edge.

`sqlstring` escaped MySQL and MariaDB literals, badly: a `Uint8Array` came out as `` `0` = 255 `` instead of `X'ff00'`, a plain object as `'[object Object]'`. No crash, no warning, just wrong output that looks fine until it isn’t. `Dialect.escape` handles all three SQL dialects itself now, byte-for-byte identical across 29 value shapes, and those two cases throw instead of writing garbage.

`reflect-metadata` (264 KB) earned its keep with one call, `Reflect.getMetadata('design:type', ...)`, so `@Field()` could guess a column’s type from the property. Optional as of this release, gone two releases later.

`jiti` (1.8 MB), a full TypeScript transpiler, existed to read one file: `uql.config.ts`. That’s a lot of compiler to hire for one sticky note. Also gone; that config now needs a runtime that already speaks TypeScript (`bun`, or `node --import tsx`).

Then the stuff that was never code: 369 sourcemaps nobody opened, and a 108 KB CHANGELOG, shipped in every install anyway. `files` in `package.json` is `["dist", "README.md"]` now.

## Then reflection went too

Two releases later, `reflect-metadata` stopped being optional and started being pointless. `0.23.0` moved decorators to the [TC39 standard spec](https://github.com/tc39/proposal-decorators): `@Field()` and `@Id()` require an explicit `type` now, checked against the property, so there’s nothing left to reflect. The full story, including what it cost, is in [Standard decorators: props & cons](https://uql-orm.dev/blog/standard-decorators.md).

## What one `npm i` puts on disk

Install one package into an empty project and count the bytes yourself:

```sh
npm i --omit=dev uql-orm
find node_modules -type f -exec cat {} + | wc -c
```

Unpacked bytes on disk, not the 288 kB you download. Tarballs compress; cold starts don’t care.

| Package | Installed | Files |
| - | - | - |
| `uql-orm` 0.24.1 | 1.0 MB | 384 |
| `@mikro-orm/postgresql` 7.1.9 | 4.7 MB | 1,153 |
| `drizzle-orm` 0.45.2 | 9.9 MB | 2,667 |
| `sequelize` 6.37.8 | 15.0 MB | 2,708 |
| `typeorm` 1.1.0 | 22.5 MB | 3,663 |
| `@prisma/client` 7.9.1 | 75.0 MB | 94 |

One thing to hold against this table before you screenshot it: 93% of `@prisma/client` is 70 MB of Rust query compilers cross-compiled to WebAssembly, one per engine it supports, which is either an engineering marvel or a cry for help. UQL ships every dialect too, so that part isn’t a fair hit on Prisma. Per dialect it’s actually smaller: 4.9 MB for its Postgres compiler alone against 19.9 kB gzipped for UQL’s entire Postgres entry point.

No row includes a driver. Add `pg` to any of them and they all grow the same amount. This table is the floor.

## What the small number doesn’t cover

UQL is the small number here, your driver isn’t. `pg`, `mysql2`, `mariadb`, `mongodb` and `better-sqlite3` all have their own weight, and the last one needs a native build. UQL’s promise is narrower than “small”: it adds nothing on top of whichever one you already picked.

Every entry point has a gzip budget checked on every build, because 0.13.0 once let `node:async_hooks` leak into browser bundles and had to be pulled. Lesson learned, budget added.

## Get started

```sh
npm i uql-orm
```

- **[Quick Start](https://uql-orm.dev/getting-started.md)**
- **[Standard decorators: props & cons](https://uql-orm.dev/blog/standard-decorators.md)**
- **[Comparison](https://uql-orm.dev/comparison.md)**
- **[GitHub](https://github.com/rogerpadilla/uql)**

If your install contains something that shouldn’t be there, open an issue.

---

---

*[UQL](https://uql-orm.dev/index.md) is a JSON-native TypeScript ORM for Node.js, Bun and Deno. Supports PostgreSQL, PGlite, MySQL, MariaDB, MSSQL, SQLite, CockroachDB, Turso, Neon, Cloudflare D1 and MongoDB. Queries are plain JSON, typed to the leaf.*
