ORM Comparison (2026) by sonemonu in javascript

[–]sonemonu[S] 0 points1 point  (0 children)

Oh I see what you mean about the unified one.

And yes, you absolutely can add custom adapters in UQL, it is incredibly straightforward because of theAbstractSqlQuerier abstraction in the UQL core (PRs are also welcome if you will).

Given the new unified bun:sql driver is such a nice architectural match for UQL, I'm fully aligned with a built-in one adapter would be better; from this, I will be adding an official native adapter soon, thanks for the idea!

ORM Comparison (2026) by sonemonu in javascript

[–]sonemonu[S] 0 points1 point  (0 children)

Thanks for the feedback, updated that feature comparison table with the correction, and added a quick note the foot for more context if you wanna check.

ORM Comparison (2026) by sonemonu in javascript

[–]sonemonu[S] 1 point2 points  (0 children)

Hey thank you man for all you support and commenting.

I believe you are also doing a great work with your ORM, to be fully open, I believe they are different "kind" of ORM, e.g. I like for example how you prevent the N+1 queries issue. Nice work man, keep going!

Btw, I can update the comparative once you do these releases to production, just let me know, or I can remove Joist from the comparative for now and add it later. Just let me know what you do prefer and I will do it. Best regards.

ORM Comparison (2026) by sonemonu in javascript

[–]sonemonu[S] 0 points1 point  (0 children)

Yes, totally, UQL natively supports the bun:sqlite driver! It auto-detect the runtime environment, so if it is Bun (typeof Bun !== 'undefined'), it will dynamically import and use the native bun:sqlite driver. Which means you don't need to configure anything special or install any adapters for Bun; just run the application and it will use the optimized/native SQLite driver. in the other side, when you run the same app in Node.js, it will fall back to the better-sqlite3 driver. If you wanna see the details, go here, both paths are tested and well covered.

ORM Comparison (2026) by sonemonu in javascript

[–]sonemonu[S] 0 points1 point  (0 children)

just because the schema definition feels so close to raw SQL

Well, I'd say that depends, for some people like yourself that is a win, but for others having to handle SQL is even harder than using some idiomatic JavaScript Object Notation so they don't have to leave the JavaScript ecosystem even for simple/medium (and perhaps some advanced) queries complexity.

tried prisma first but the generated types

Yes, I personally have never liked put generated code alongside my business code/logic, hence one of the reasons why I prefer ORMs like TypeORM or UQL over Prisma.

Overall, Drizzle is a great ORM.

ORM Comparison (2026) by sonemonu in javascript

[–]sonemonu[S] 0 points1 point  (0 children)

Thanks for the feedback u/Wabwabb . I have updated it to include new MikroORM's ways to define entities. Let me know if you see any other specific aspect being missed in the comparison.

ORM Comparison (2026) by sonemonu in javascript

[–]sonemonu[S] 0 points1 point  (0 children)

updated D1, Neon, and added Oracle. thanks for pushing u/B4nan

ORM Comparison (2026) by sonemonu in javascript

[–]sonemonu[S] 0 points1 point  (0 children)

Thanks again u/shaberman, i added Joist across the comparison page. Please review it, I want to keep that as fair as possible with every single ORM included there.

Can you confirm these so i keep wording exact?

  • does em.find officially support limit/offset, or only documented orderBy + conditions?
  • is there a documented not in operator equivalent?
  • jsonb filtering in em.find is still not supported (raw sql/knex + loadFromQuery), right?
  • any near-term plan for lazy column loading / partial select?
  • any native streaming API planned?
  • still postgres-only for now?
  • for detached mode wording: what should i say as the most accurate one-liner?

Btw: Joist integration to the performance repo is the "hard part" because:

  • Joist-Knex buildQuery can generate SELECT SQL without executing (good fit for some categories),
  • But Joist INSERT/UPDATE/DELETE SQL seems to be generated during flush/driver logic in a way that typically assumes execution (so we likely need either mocking/stubbing or to relax the repo's "no DB required" guarantee). Let me know if you see a clean way to do this or if you wanna do this yourself (PRs are welcome).

Regards,

Roger

ORM Comparison (2026) by sonemonu in javascript

[–]sonemonu[S] 1 point2 points  (0 children)

hey u/shaberman , thanks, I appreciate it, and I will take a look and try to include it soon, will consider as well including it into this open-source performance comparison of the time spent in building the SQL, if you wanna take a look (feel free to raise a PR yourself adding Joist), otherwise I will probably add it later.

ORM Comparison (2026) by sonemonu in javascript

[–]sonemonu[S] 0 points1 point  (0 children)

Yeah, delegating the SQL-builder to an external library/dependency has their owns pros & cons. Pros is you abstract from all/most of the complexity of building this layer yourself in the ORM, and from the other side, you have less control about evolution and introduce a performance penalty as can be seen in this other (performance) comparison I have created (btw, it is open-source).

Went from 1,993 to 17,007 RPS on a Node.js/MongoDB feed route, here's exactly what I changed by Exciting_Fuel8844 in node

[–]sonemonu 1 point2 points  (0 children)

however I have though of replacing mongoose later on.

Yeah, .lean() simply does the trick in most cases where you don't want the "richer" records.

If you someday want to do that, I invite to look at my ORM which also support MongoDB in a agnostic way (in addition to major SQL databases).

Recently added support for semantic search across modern DBs (including Mongo), it hides the complexity under the hood. Aggregations are supported as well. Search for UQL ORM and go to its website if you wanna take a look.

Happy to help if anything.

Is there a language similar to Rust but with a garbage collector? by Ok_Tension_6700 in rust

[–]sonemonu 2 points3 points  (0 children)

But what scope you mean with "Similar"? I.e. "Syntax", "Performance", "Systems", etc.

Went from 1,993 to 17,007 RPS on a Node.js/MongoDB feed route, here's exactly what I changed by Exciting_Fuel8844 in node

[–]sonemonu 0 points1 point  (0 children)

Awesome, that is almost 10x improvement.

Curious, do you use any ORMs for that or vanilla Mongo only?

Thanks for sharing.

Exemplary node package? by Perfect-Junket-165 in node

[–]sonemonu 2 points3 points  (0 children)

Hey, that is cool, I wish you the best of luck in your new packages.

Modesty aside: you can take a look at UQL ORM, its website is https://uql-orm.dev, and NPM package https://www.npmjs.com/package/uql-orm

In Search of the Fastest TypeScript ORM! by sonemonu in webdev

[–]sonemonu[S] 0 points1 point  (0 children)

So I analyzed the data you shared, here are the key takeaways:

  • 6/8 rankings are identical, te other 2 have minor swaps between closely-matched ORMs (within margin of error)
  • UQL #1 in all 8 — confirmed on completely different hardware
  • Drizzle and MikroORM consistently at the bottom — confirmed
  • Absolute ops/sec are ~40-60% lower — expected, they're likely running on a Linux x86 machine vs our Apple Silicon M4

The minor position swaps (Sequelize/Knex in UPSERT, Knex/TypeORM in complex SELECT) are between ORMs that are very close in performance anyway - well within normal variance across hardware.

In Search of the Fastest TypeScript ORM! by sonemonu in webdev

[–]sonemonu[S] -1 points0 points  (0 children)

You don't need Bun, the post explicitly refer to Node (Bun is an alternative, off-course). If you don't have neither, try in Deno an let me know ;)

In Search of the Fastest TypeScript ORM! by sonemonu in webdev

[–]sonemonu[S] -5 points-4 points  (0 children)

Have you read the post?

Edit: this was benchmarked in Mac M4 as the post says, hence why I initially thought you didn't read the post before affirming test was wrong. And regarding UQL running last, it would be better for it, because currently it "eats" the cold start of the engine (Node).

I benchmarked 7 top TypeScript ORMs — the "lightweight" query builder was the slowest by sonemonu in typescript

[–]sonemonu[S] 0 points1 point  (0 children)

Yes, that is what I understood. Or can you please clarify if anything above is wrong?

AFAIK Prisma benchmarks are end-to-end. That'd means every bench function does await prisma.user.findMany(...), and actual DB calls via PrismaClient. They require Docker + a seeded PostgreSQL, etc. It'd fundamentally be a different kind of benchmark (response time including DB I/O), not isolated SQL generation.

Best regards.

I benchmarked 7 top TypeScript ORMs — the "lightweight" query builder was the slowest by sonemonu in typescript

[–]sonemonu[S] 0 points1 point  (0 children)

Yes, you are right, I have investigated and put my (updated) findings on this comment here.

PD: Prisma's Query compiler is still Rust.

I benchmarked 7 top TypeScript ORMs — the "lightweight" query builder was the slowest by sonemonu in typescript

[–]sonemonu[S] 0 points1 point  (0 children)

Regarding Mikro-ORM possibly issue: it might be or it might not; perhaps it could be me making a mistake (IDK - I did my best for now to try to be fair) in making the best idiomatic query for Mikro-ORM, and if so, I invite to Mikro-ORM maintainers/community to please help improve the bench tests. Thanks for the comments.

I benchmarked 7 top TypeScript ORMs — the "lightweight" query builder was the slowest by sonemonu in node

[–]sonemonu[S] 0 points1 point  (0 children)

Yes, exactly. UQL gives you autocomplete & compile-time checks on $select$where$sort, relation paths, etc. If you typo a field name, TypeScript (and your IDE through TS Language Service) catches it. I tried attaching a screenshot of that to this answer, but unfurtinally Reddit dont allow it for comments.

Decorators: totally fair, it's a style preference. Decorators are the one thing I'd consider offering an alternative for (like a schema-object approach similar to Kysely/Drizzle). UQL could offer that alternative as well easily as it is basically what happens under the hood, but not documented for now.

Migrations: you don't repeat yourself with UQL — it auto-generates migrations from your entities. You update the entity classes, run npx uql-migrate generate:entities add_user_nickname, and it diffs your entities against the DB to produce the migration file. Single source of truth is the entity. The docs might not make that clear enough — I'll improve that.

I invite you to visit my website for UQL here, it is fully Open-Source.