nestjs-drizzle-crud vs @nestjsx/crud

nestjs-drizzle-crud vs @nestjsx/crud compared. One builds CRUD on Drizzle ORM, the other on TypeORM, with a different query syntax and release history.

nestjs-drizzle-crud vs @nestjsx/crud comes down to your ORM and how current you need the library to be. @nestjsx/crud generates REST controllers with a @Crud() decorator and ships a TypeORM service and a frontend request builder. nestjs-drizzle-crud gives you a CRUD service for Drizzle ORM tables, a query string parser and an optional controller factory. The last stable @nestjsx/crud release is from May 2020.

How this page was checked

Facts about @nestjsx/crud come from its own README, wiki, source and npm entry, checked on 2 November 2026, with a link next to each one. Facts about nestjs-drizzle-crud come from the package source at version 3.6.0. If something here has changed upstream, the linked source wins.

How do the two libraries differ at a glance?

They solve the same problem (stop writing the same list, get, create, update and delete code per entity) from opposite ends: @nestjsx/crud starts from the controller, nestjs-drizzle-crud starts from the service.

nestjs-drizzle-crud@nestjsx/crud
ORMDrizzle ORM (drizzle-orm from 0.28.0 up to, not including, 1.0.0)TypeORM, through @nestjsx/crud-typeorm
DatabasesPostgreSQL and MySQL (dialect: "postgresql" | "mysql")Through TypeORM; the README lists no databases of its own
Entry pointSqlBaseCrudService subclass per table@Crud() decorator on a controller
Generated routesOptional, with createCrudControllerAlways, from @Crud()
Query stringage[gte]=18&sortBy=-name&with=regionfilter=age||$gte||18&sort=name,DESC&join=region (wiki)
Frontend query builderNoYes, RequestQueryBuilder in @nestjsx/crud-request
Replace (PUT) routeNoYes, replaceOneBase (wiki)
Soft deleteYes, on by default, with restore, trash and force deleteYes, query.softDelete plus a recover route in the source
Keyset (cursor) paginationYes, findByCursorNot documented
Optimistic locking, tenant scopes, upsertYesNot documented
LicenseMITMIT

"Not documented" means the README and wiki do not describe it. It does not mean it is impossible to build on top.

What is the current state of @nestjsx/crud?

As of November 2026 the npm and GitHub records show no release since early 2021:

FactValueSource
Latest version on npm (latest tag)5.0.0-alpha.3, published 11 February 2021npm registry
Last non-prerelease version4.6.2, published 14 May 2020npm registry
Last commit on master7 December 2022commit history
Repository archivedNoGitHub
Open issues and pull requests290GitHub
Packages@nestjsx/crud, @nestjsx/crud-request, @nestjsx/crud-typeormREADME

A community fork, @dataui/crud (gid-oss/dataui-nestjs-crud), last published 5.3.4 on 9 April 2024, also as of November 2026.

What does @nestjsx/crud do better?

Three things, all documented in its own README:

  • A frontend request builder. RequestQueryBuilder from @nestjsx/crud-request builds the query string in the browser, so client code does not concatenate || strings by hand. nestjs-drizzle-crud has no client package.
  • Controllers first. One @Crud() decorator registers every route, including PUT replace and POST /bulk. In nestjs-drizzle-crud the bulk routes are off until you turn them on, and there is no PUT.
  • TypeORM. If your entities are TypeORM classes and you do not plan to move, nestjs-drizzle-crud cannot use them: it reads Drizzle table objects.

What does nestjs-drizzle-crud do that @nestjsx/crud does not document?

Everything below is in the nestjs-drizzle-crud source today:

  • Keyset pagination with findByCursor and ?cursor=, beside offset pages. See Cursor pagination.
  • Collection filters with some, none and every on has-many and many-to-many relations, compiled to subqueries so total stays right. See Relation filters.
  • Allowlists for filter, sort, select, search, load and write, each one a 400 when broken. See Allowlists.
  • Writes beyond create and update: upsert, massUpdate, massSoftDelete, restore, forceDelete, optimistic locking and row locks.
  • Tenant scopes read from a per-request CrudContext. See Multi-tenancy.
  • Typed exceptions that map to 404, 409 and 400 without a custom filter. See Errors.

How do the query strings compare?

Both libraries read filters, sort, pagination, field selection and relations from the URL, with different syntax. The same request in each:

Intentnestjs-drizzle-crud@nestjsx/crud
Exact matchname=Asiafilter=name||$eq||Asia
Operatorpopulation[gte]=1000000filter=population||$gte||1000000
ORor[0][code]=IN&or[1][code]=NPor=code||$eq||IN&or=code||$eq||NP
SortsortBy=-name,idsort=name,DESC&sort=id,ASC
Pagepage=2&limit=20page=2&limit=20
Fieldsfields=id,namefields=id,name
Relationwith=regionjoin=region
Relation column filterregion[name]=Asiajoin=region&filter=region.name||$eq||Asia

In nestjs-drizzle-crud a bare value on a text column (name=Asia) is case-insensitive while sql.caseSensitive is false, the default; name[eq]=Asia is a plain =. The full operator mapping is on Migrating from @nestjsx/crud. Note that in nestjs-drizzle-crud an unknown column or operator is always a 400, never ignored. See Parse query strings into filters.

When should I choose @nestjsx/crud?

Choose @nestjsx/crud when:

  • your project is on TypeORM and will stay there,
  • you already run it in production and it does what you need, or
  • you want the RequestQueryBuilder client and the generated PUT route.

Check that its peer and transitive dependencies fit your NestJS and TypeORM versions first, given that the last stable release dates from May 2020.

When should I choose nestjs-drizzle-crud?

Choose nestjs-drizzle-crud when:

  • your schema is in Drizzle ORM, or you are moving to it,
  • you want the CRUD logic in a service you can call from code, jobs and controllers alike,
  • you need cursor pagination, upsert, tenant scopes or optimistic locking without writing them, or
  • you want a library with recent releases (see the changelog).

It is not the right pick on TypeORM or Prisma, or on a database other than PostgreSQL or MySQL.

Common questions

Next steps

Last updated View change history

On this page