mk668a/nestjs-prisma-graphql-crud-gen

Generate CRUD resolvers from GraphQL schema with NestJS and Prisma

47

stars

45

commits

TypeScript

primary language

Jul 21, 2026

updated

www.npmjs.com/package/nestjs-prisma-graphql-crud-gen
crud
generator
graphql
nestjs
prisma
prisma-generator
resolvers
typescript
Browse cluster: Prisma code generation and GraphQL

README

icon

NestJS Prisma GraphQL CRUD Generator (v2)

Schema-driven NestJS + GraphQL CRUD bindings for Prisma. Generates a thin per-model resolver / service / module that delegates heavy lifting to a shared runtime package, so updates ship without forcing you to regenerate everything.

Why v2?

v1 generated ~10+ files per model (resolver, service, module, args, inputs, outputs, model, …). v2 collapses resolver+service+module into a single <model>.crud.ts and moves shared behavior (error mapping, soft-delete, DataLoader, common filters) into nestjs-prisma-graphql-crud-gen-runtime. The result:

  • ~80% fewer generated files
  • Library updates land via runtime bumps — no re-generation required for bug fixes
  • Cross-cutting concerns are correct every time (validation, error mapping, soft-delete) — the deterministic edge over hand-rolled or AI-generated scaffolds

Requirements

  • Node.js >= 20
  • Prisma >= 7.x
  • NestJS >= 10, @nestjs/graphql >= 12

Quickstart

yarn add nestjs-prisma-graphql-crud-gen nestjs-prisma-graphql-crud-gen-runtime

In schema.prisma:

generator nestjs_graphql_crud {
  provider = "nestjs-prisma-graphql-crud-gen"
  output   = "../generated"
}

In your NestJS root module, provide PRISMA_CLIENT for the runtime to consume:

import { PRISMA_CLIENT } from 'nestjs-prisma-graphql-crud-gen-runtime'
import { PrismaService } from './prisma.service' // your own PrismaService

@Module({
  providers: [PrismaService, { provide: PRISMA_CLIENT, useExisting: PrismaService }],
  exports: [PRISMA_CLIENT],
})
export class PrismaModule {}

Then run:

npx prisma generate

Generator options

Set on the generator block in schema.prisma:

generator nestjs_graphql_crud {
  provider              = "nestjs-prisma-graphql-crud-gen"
  output                = "../generated"
  useNormalizedNaming   = "true"      # default; "Users" model -> GraphQL "User"
  emitValidation        = "false"     # class-validator decorators on inputs
  emitDataLoader        = "false"     # per-relation DataLoader N+1 helpers
  emitFederation        = "false"     # Apollo Federation v2 @key directives
  emitOnly              = "models,crud,inputs,outputs,enums"  # subset to emit
  runtimeImportPath     = "nestjs-prisma-graphql-crud-gen-runtime"
}

Triple-slash directives

Annotate the schema to opt into v2 behaviors. Place them on the line above the field or model.

DirectiveTargetEffect
/// @HideFieldfieldHide field from both GraphQL input and output
/// @HideField({ input: true, output: false })fieldSelective hiding
/// @ReadOnlyfieldSkip in Create / Update input types
/// @SoftDeletemodeldelete -> update({ deletedAt: now() }); find queries auto-filter deletedAt IS NULL
/// @SoftDelete({ field: "archivedAt" })modelUse a non-default soft-delete field
/// @Crud(only: ["findMany", "findUnique"])modelEmit only the listed CRUD operations
/// @Crud(except: ["delete", "deleteMany"])modelEmit all CRUD ops except listed
/// @Validate({ minLength: 3, isEmail: true })fieldclass-validator decorators on inputs
/// @Auth(roles: ["admin"])modelEmit @UseGuards + @Roles() on resolver

Example:

/// @SoftDelete
model User {
  id        String   @id @default(cuid())
  /// @HideField({ output: true })
  password  String
  /// @Validate({ isEmail: true })
  email     String   @unique
  /// @ReadOnly
  createdAt DateTime @default(now())
  deletedAt DateTime?
}

Generated layout

For a model Users { ... } (note plural in Prisma), with useNormalizedNaming: true (the default):

generated/
├── common/
│   ├── inputs/        # Prisma-generated common inputs (StringFilter, ...)
│   └── outputs/       # AffectedRowsOutput, etc.
├── enums/
├── models/
│   └── user.model.ts  # @ObjectType('User')
└── user/
    ├── user.args.ts   # FindFirstUserArgs, CreateOneUserArgs, ...
    ├── user.crud.ts   # UserResolver + UserService + UserModule
    ├── inputs/
    └── outputs/

prisma.users (plural) is still used for the Prisma client delegate call inside the service. Only the GraphQL surface is singularized.

Migration from v1

See MIGRATION.md.

Sample project

See usage/ in this repository, and nestjs-graphql-starter.

Contributing

See CONTRIBUTING.md. The repo uses Jest snapshot tests under packages/generator/__tests__/.

License

MIT

Contributors

mk668a

35 commits

MinJungHyun

1 commits

mk668a/nestjs-prisma-graphql-crud-gen

Generate CRUD resolvers from GraphQL schema with NestJS and Prisma

47

stars

45

commits

TypeScript

primary language

Jul 21, 2026

updated

www.npmjs.com/package/nestjs-prisma-graphql-crud-gen
crud
generator
graphql
nestjs
prisma
prisma-generator
resolvers
typescript
Browse cluster: Prisma code generation and GraphQL

README

icon

NestJS Prisma GraphQL CRUD Generator (v2)

Schema-driven NestJS + GraphQL CRUD bindings for Prisma. Generates a thin per-model resolver / service / module that delegates heavy lifting to a shared runtime package, so updates ship without forcing you to regenerate everything.

Why v2?

v1 generated ~10+ files per model (resolver, service, module, args, inputs, outputs, model, …). v2 collapses resolver+service+module into a single <model>.crud.ts and moves shared behavior (error mapping, soft-delete, DataLoader, common filters) into nestjs-prisma-graphql-crud-gen-runtime. The result:

  • ~80% fewer generated files
  • Library updates land via runtime bumps — no re-generation required for bug fixes
  • Cross-cutting concerns are correct every time (validation, error mapping, soft-delete) — the deterministic edge over hand-rolled or AI-generated scaffolds

Requirements

  • Node.js >= 20
  • Prisma >= 7.x
  • NestJS >= 10, @nestjs/graphql >= 12

Quickstart

yarn add nestjs-prisma-graphql-crud-gen nestjs-prisma-graphql-crud-gen-runtime

In schema.prisma:

generator nestjs_graphql_crud {
  provider = "nestjs-prisma-graphql-crud-gen"
  output   = "../generated"
}

In your NestJS root module, provide PRISMA_CLIENT for the runtime to consume:

import { PRISMA_CLIENT } from 'nestjs-prisma-graphql-crud-gen-runtime'
import { PrismaService } from './prisma.service' // your own PrismaService

@Module({
  providers: [PrismaService, { provide: PRISMA_CLIENT, useExisting: PrismaService }],
  exports: [PRISMA_CLIENT],
})
export class PrismaModule {}

Then run:

npx prisma generate

Generator options

Set on the generator block in schema.prisma:

generator nestjs_graphql_crud {
  provider              = "nestjs-prisma-graphql-crud-gen"
  output                = "../generated"
  useNormalizedNaming   = "true"      # default; "Users" model -> GraphQL "User"
  emitValidation        = "false"     # class-validator decorators on inputs
  emitDataLoader        = "false"     # per-relation DataLoader N+1 helpers
  emitFederation        = "false"     # Apollo Federation v2 @key directives
  emitOnly              = "models,crud,inputs,outputs,enums"  # subset to emit
  runtimeImportPath     = "nestjs-prisma-graphql-crud-gen-runtime"
}

Triple-slash directives

Annotate the schema to opt into v2 behaviors. Place them on the line above the field or model.

DirectiveTargetEffect
/// @HideFieldfieldHide field from both GraphQL input and output
/// @HideField({ input: true, output: false })fieldSelective hiding
/// @ReadOnlyfieldSkip in Create / Update input types
/// @SoftDeletemodeldelete -> update({ deletedAt: now() }); find queries auto-filter deletedAt IS NULL
/// @SoftDelete({ field: "archivedAt" })modelUse a non-default soft-delete field
/// @Crud(only: ["findMany", "findUnique"])modelEmit only the listed CRUD operations
/// @Crud(except: ["delete", "deleteMany"])modelEmit all CRUD ops except listed
/// @Validate({ minLength: 3, isEmail: true })fieldclass-validator decorators on inputs
/// @Auth(roles: ["admin"])modelEmit @UseGuards + @Roles() on resolver

Example:

/// @SoftDelete
model User {
  id        String   @id @default(cuid())
  /// @HideField({ output: true })
  password  String
  /// @Validate({ isEmail: true })
  email     String   @unique
  /// @ReadOnly
  createdAt DateTime @default(now())
  deletedAt DateTime?
}

Generated layout

For a model Users { ... } (note plural in Prisma), with useNormalizedNaming: true (the default):

generated/
├── common/
│   ├── inputs/        # Prisma-generated common inputs (StringFilter, ...)
│   └── outputs/       # AffectedRowsOutput, etc.
├── enums/
├── models/
│   └── user.model.ts  # @ObjectType('User')
└── user/
    ├── user.args.ts   # FindFirstUserArgs, CreateOneUserArgs, ...
    ├── user.crud.ts   # UserResolver + UserService + UserModule
    ├── inputs/
    └── outputs/

prisma.users (plural) is still used for the Prisma client delegate call inside the service. Only the GraphQL surface is singularized.

Migration from v1

See MIGRATION.md.

Sample project

See usage/ in this repository, and nestjs-graphql-starter.

Contributing

See CONTRIBUTING.md. The repo uses Jest snapshot tests under packages/generator/__tests__/.

License

MIT

Contributors

mk668a

35 commits

MinJungHyun

1 commits

Languages

TypeScript

97.6%

Shell

1.4%