npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

prisma-nestjs-graphql

v23.2.1

Published

Generate object types, inputs, args, etc. from prisma schema file for usage with @nestjs/graphql module

Downloads

90,817

Readme

prisma-nestjs-graphql

Generate object types, inputs, args, etc. from prisma schema file for usage with @nestjs/graphql module.

Features

  • Generates only necessary imports
  • Combines zoo of nested/nullable filters
  • Does not generate resolvers, since it's application specific

Install

npm install --save-dev prisma-nestjs-graphql @prisma/generator-helper identity-type

Usage

  1. Add new generator section to schema.prisma file
generator nestgraphql {
  provider = "prisma-nestjs-graphql"
  // Or explicit node execution
  provider = "node node_modules/prisma-nestjs-graphql/bin.mjs"
  output = "../src/@generated"
}
  1. Add a configuration file

Create prisma/nestgraphql.config.mjs and reference it in your schema:

generator nestgraphql {
  provider = "prisma-nestjs-graphql"
  configFile = "./nestgraphql.config.mjs"
}
// prisma/nestgraphql.config.mjs
/**
 * @type {import('prisma-nestjs-graphql').ExternalConfig}
 */
export default {
  output: '../src/@generated',
};

All generator options—including decorators, fields, useInputType, customImport, and graphqlScalars—are defined as structured JavaScript objects in the config file instead of using underscore-delimited keys (decorate_1_*, fields_Validator_*, etc.) directly in the schema.

  1. Run prisma generate
npx prisma generate
  1. If your models have Decimal and Json types, you need install:
npm install graphql-type-json prisma-graphql-type-decimal

Or write you own graphql scalar types, read more on docs.nestjs.com.

Configuration File

Instead of defining all options as flat keys in schema.prisma, you can use a structured JavaScript config file for better readability, validation, and IDE autocompletion.

Migration from flatten-style keys

Before (underscore-delimited keys in schema.prisma):

fields_Validator_from = "class-validator"
fields_Validator_input = true
decorate_1_type = "CreateOneUserArgs"
decorate_1_field = data
decorate_1_from = "class-validator"
decorate_1_name = ValidateNested
decorate_1_arguments = "[]"

After (structured objects in nestgraphql.config.mjs):

fields: {
  Validator: { from: 'class-validator', input: true },
},
decorators: [
  {
    match: ({ objectName, propertyName }) =>
      objectName === 'CreateOneUserArgs' && propertyName === 'data',
    from: 'class-validator',
    name: 'ValidateNested',
    arguments: [],
    namedImport: true,
  },
],

Backward compatibility

The old flatten-style keys still work if no configFile is specified. Options from the config file take precedence.

Generator options

output

Output folder, if path relative and defined in schema it will be relative to schema, if defined in config file it will be relative to this config file. Type: string

outputFilePattern

File path and name pattern
Type: string
Default: {model}/{name}.{type}.ts
Possible tokens:

  • {model} Model name in dashed case or 'prisma' if unknown
  • {name} Dashed-case name of model/input/arg without suffix
  • {type} Short type name (model, input, args, output)
  • {plural.type} Plural short type name (models, inputs, enums)

tsConfigFilePath

Path to tsconfig.json (absolute path or relative to current working directory)
Type: string | undefined
Default: tsconfig.json if exists, undefined otherwise

prismaClientImport

The path to use to import the Prisma Client package Type: string | undefined Default: @prisma/client

importExtension

Append an extension to relative import and export module specifiers (without dot, eg. 'js, 'ts', 'mjs') Type: string Default: '' (empty string)

combineScalarFilters

Combine nested/nullable scalar filters to single Type: boolean Default: true

noAtomicOperations

Remove input types for atomic operations Type: boolean Default: true

reExport

Create index.ts file with re-export Type: enum Values: None Default, create nothing Directories Create index file in all root directories Single Create single index file in output directory All Create index file in all root directories and in output directory

Example configuration:

generator nestgraphql {
    provider = "node node_modules/prisma-nestjs-graphql"
    output = "../src/@generated"
    reExport = Directories
}

emitSingle

Generate single file with merged classes and enums. Type: boolean Default: false

emitCompiled

Emit compiled JavaScript and definitions instead of TypeScript sources. Type: boolean Default: false

emitBlocks

Emit only selected blocks. Be aware, that some blocks do depend on others, e.g. one can't emit models without emitting enums. Type: ("args" | "inputs" | "outputs" | "models" | "enums")[] Default: ["args", "inputs", "outputs", "models", "enums"]

omitModelsCount

Omit _count field from models. Type: boolean Default: false

purgeOutput

Delete all files in output folder. Type: boolean Default: false

noTypeId

Disable usage of graphql ID type and use Int/Float for fields marked as @id in schema. Type: boolean Default: false

typeListNullable

Adds nullable: true for relation list properties out output models, it makes graphql field looks like [Type!], default [Type!]! Type: boolean Default: false

requireSingleFieldsInWhereUniqueInput

When a model *WhereUniqueInput class has only a single field, mark that field as required (TypeScript) and not nullable (GraphQL). See #58 for more details. Type: boolean Default: false Note: It will break compatiblity between Prisma types and generated classes.

unsafeCompatibleWhereUniqueInput

Set TypeScript property type as non optional for all fields in *WhereUniqueInput classes. See #177 for more details. Type: boolean Default: false

inputType

Since GraphQL does not support input union type, this setting map allow to choose which input type is preferable.

New (config file):

/**
 * Input type mapping.
 * Select which input type should be exposed when multiple candidates exist.
 * Since GraphQL does not support input unions, this setting can resolve
 * ambiguous fields (e.g. `UserRelationFilter` vs `UserWhereInput`).
 *
 * Supports two variants:
 * - object map: `{ [inputTypeName]: { [fieldName|'*']: pattern } }`
 * - function: return either an `InputTypeRef` or a string pattern
 *   (same matching behavior as map patterns, including `match:` syntax)
 * @example
 * // Force all WhereInput relation properties to use the plain WhereInput type:
 * { WhereInput: { '*': 'WhereInput' } }
 * // Or for a specific property in a specific type:
 * { PostCreateInput: { author: 'UserCreateNestedOneWithoutPostsInput' } }
 * // Function variant returning a pattern:
 * ({ inputTypeName, fieldName }) =>
 *   inputTypeName.includes('CreateOne') && fieldName === 'data'
 *     ? 'UncheckedCreate'
 *     : undefined
 */
inputType: GetInputTypeFunction | ConfigInputTypeMap;

Where:

  • typeName — Full or partial name of the class where need to choose input type
  • property — Property of the class. Special case ALL means any/all properties
  • pattern — Part of name (or full) of type to choose; use match:*UncheckedCreateInput for wildcard/negation matching

Legacy (schema.prisma, flatten-style):

generator nestgraphql {
  useInputType_{typeName}_{property} = "{pattern}"
}

Example:

export type PostWhereInput = {
  author?: XOR<UserRelationFilter, UserWhereInput>;
};
export type UserRelationFilter = {
  is?: UserWhereInput;
  isNot?: UserWhereInput;
};

export type UserWhereInput = {
  AND?: Enumerable<UserWhereInput>;
  OR?: Enumerable<UserWhereInput>;
  NOT?: Enumerable<UserWhereInput>;
  id?: StringFilter | string;
  name?: StringFilter | string;
};

We have generated types above, by default property author will be decorated as UserRelationFilter, to set UserWhereInput need to configure generator the following way (legacy way):

generator nestgraphql {
  provider = "node node_modules/prisma-nestjs-graphql"
  output = "../src/@generated"
  useInputType_WhereInput_ALL = "WhereInput"
}
@InputType()
export class PostWhereInput {
  @Field(() => UserWhereInput, { nullable: true })
  author?: UserWhereInput;
}

decorators

Modern way to attach custom decorators in config file (decorators: DecoratorItem[]).

decorators: [
  {
    match: ({ objectName, propertyName }) =>
      objectName === 'CreateOneUserArgs' && propertyName === 'data',
    from: 'class-validator',
    name: 'ValidateNested',
    arguments: [],
    namedImport: true,
  },
  {
    match: ({ objectName, propertyName }) =>
      objectName === 'CreateOneUserArgs' && propertyName === 'data',
    from: 'class-transformer',
    name: 'Type',
    arguments: ['() => {propertyType.0}'],
    namedImport: true,
  },
];

match receives one argument FieldInfo:

type FieldInfo = {
  /**
   * Prisma DMMF field location type
   * Can be: 'scalar', 'inputObjectTypes', 'outputObjectTypes', 'enumTypes', 'fieldRefTypes'
   */
  location: FieldLocation;
  /**
   * Class name
   */
  objectName: string;
  /**
   * Property name
   */
  propertyName: string;
  /**
   * Property type (may contain TypeScript elements, like parameters for generics, etc.)
   */
  propertyType: string;
  /**
   * GraphQL/Prisma type name
   */
  typeName: string;
};

Decorator item type:

type DecoratorItem = {
  /** Return `true` to apply this decorator to the current field. */
  match: (args: FieldInfo) => boolean;
  /** Arguments passed to the decorator call.
   * Supports templates like `{propertyType.0}`. */
  arguments?: string[];
  /** Module specifier to import from (e.g. 'class-validator') */
  from: string;
  /** Decorator name. Can include namespace, e.g. `Transform.Type`. */
  name: string;
  /** Import as a named export. */
  namedImport: boolean;
  /** Import as default export.
   * Use `true` to import by decorator name. */
  defaultImport?: string | true;
  /** Import entire module under this namespace. */
  namespaceImport?: string;
};

Special token in arguments: {propertyType.0} resolves to the field's TypeScript type.

Example result:

import { ValidateNested } from 'class-validator';
import { Type } from 'class-transformer';

@ArgsType()
export class CreateOneUserArgs {
  @Field(() => UserCreateInput, { nullable: false })
  @ValidateNested()
  @Type(() => UserCreateInput)
  data!: UserCreateInput;
}

Legacy (decorate / decorate_*)

Legacy flatten-style keys in schema.prisma are still supported for backward compatibility:

generator nestgraphql {
  decorate_{key}_type = "outmatch pattern"
  decorate_{key}_field = "outmatch pattern"
  decorate_{key}_from = "module specifier"
  decorate_{key}_name = "import name"
  decorate_{key}_arguments = "[argument1, argument2]"
  decorate_{key}_defaultImport = "default import name" | true
  decorate_{key}_namespaceImport = "namespace import name"
  decorate_{key}_namedImport = "import name" | true
}

Prefer decorators in nestgraphql.config.* for new configuration.

graphqlScalars

Allow to set custom graphql type for Prisma scalar type.

New (config file):

graphqlScalars: {
  BigInt: { name: 'GraphQLBigInt', specifier: 'graphql-scalars' },
}

Legacy (schema.prisma, flatten-style):

graphqlScalars_{type}_name = "string"
graphqlScalars_{type}_specifier = "string"

where {type} is a prisma scalar type name (e.g. BigInt)

Example:

graphqlScalars_BigInt_name = "GraphQLBigInt"
graphqlScalars_BigInt_specifier = "graphql-scalars"

May generate:

import { GraphQLBigInt } from 'graphql-scalars';

export class BigIntFilter {
  @Field(() => GraphQLBigInt, { nullable: true })
  equals?: bigint | number;
}

It will affect all inputs and outputs types (including models).

customImports

Allow to declare custom import statements. Note: Only works with emitSingle = true

New (config file):

customImports: [
  { from: 'nestjs-i18n', name: 'I18n', defaultImport: true },
  { from: 'class-transformer', name: 'Transform', namedImport: true },
];

Legacy (schema.prisma, flatten-style):

generator nestgraphql {
  customImport_{key}_from = "module specifier"
  customImport_{key}_name = "import name"
  customImport_{key}_defaultImport = "default import name" | true
  customImport_{key}_namespaceImport = "namespace import name"
  customImport_{key}_namedImport = "import name" | true
}

Where {key} any identifier to group values (written in flatten style)

  • customImport_{key}_from - module specifier to import from (e.g nestjs-i18n)
  • customImport_{key}_name - import name or name with namespace
  • customImport_{key}_defaultImport - import as default
  • customImport_{key}_namespaceImport - use this name as import namespace
  • customImport_{key}_namedImport - named import (without namespace)

fieldDecoratorArguments

Override @Field() decorator arguments for specific fields. Use this to customize pagination fields (take, skip, cursor) or other generated Args fields that don't come from your Prisma schema.

Each rule is evaluated against generated field metadata and applied when the match function returns true. Multiple matching rules are merged in order.

New (config file):

fieldDecoratorArguments: [
  {
    match: ({ objectName, propertyName }) =>
      objectName.endsWith('Args') && propertyName === 'take',
    decoratorArguments: {
      name: 'first',
      defaultValue: 10,
      description: 'Number of records to return',
    },
  },
  {
    match: ({ objectName, propertyName }) =>
      objectName.endsWith('Args') && propertyName === 'skip',
    decoratorArguments: {
      name: 'offset',
      defaultValue: 0,
      description: 'Number of records to skip',
    },
  },
]

Available decoratorArguments options:

  • nullable — Mark field as nullable in GraphQL schema
  • defaultValue — Default value for the field
  • description — Description shown in GraphQL schema
  • deprecationReason — Mark field as deprecated
  • name — Custom name for the field in GraphQL schema (TypeScript property name stays the same)
  • complexity — Complexity value for query cost analysis
  • middleware — Middleware function name(s) to apply to the field

Middleware Example:

To use field middleware, combine customImports with fieldDecoratorArguments. Middleware values are emitted as identifier references (not string literals), allowing them to reference your imported middleware functions:

export default {
  customImports: [
    { from: './middleware/logger', name: 'loggerMiddleware', defaultImport: true },
    { from: './middleware/auth', name: 'authMiddleware', defaultImport: true },
  ],
  fieldDecoratorArguments: [
    {
      match: ({ objectName, propertyName }) =>
        objectName === 'User' && propertyName === 'email',
      decoratorArguments: {
        middleware: ['loggerMiddleware', 'authMiddleware'],
        description: 'User email with logging and auth',
      },
    },
  ],
};

This generates:

@Field(() => String, {
  description: 'User email with logging and auth',
  middleware: [loggerMiddleware, authMiddleware]
})
email: string;

Note: When using the name option to override a field name in GraphQL, ensure you understand Prisma field mapping. For example, if you override the take field name to first, you must update any Prisma query logic that references the field by its original name. Consider using a mapping helper if doing this across multiple queries.

The match function receives FieldInfo with:

  • objectName — Class name (e.g., 'FindManyUserArgs')
  • propertyName — Property name (e.g., 'take', 'skip')
  • propertyType — TypeScript property type
  • typeName — GraphQL/Prisma type name
  • location — Prisma field location ('scalar', 'inputObjectTypes', etc.)

Documentation and field options

Comments with triple slash will projected to typescript code comments and some @Field() decorator options

For example:

model Product {
  /// Old description
  /// @deprecated Use new name instead
  /// @complexity 1
  oldName String
}

May produce:

@ObjectType()
export class Product {
  /**
   * Old description
   * @deprecated Use new name instead
   */
  @Field(() => String, {
    description: 'Old description',
    deprecationReason: 'Use new name instead',
    complexity: 1,
  })
  oldName: string;
}

Field Settings

Special directives in triple slash comments for more precise code generation.

@HideField()

Removes field from GraphQL schema. By default (without arguments) field will be decorated for hide only in output types (type in schema). To hide field in input types add input: true. To hide field in specific type you can use glob pattern match: string | string[] see outmatch for details.

For config-file based rules, use shouldHideField:

export default {
  shouldHideField: ({ location, objectName, propertyName }) =>
    location === 'inputObjectTypes' &&
    objectName.endsWith('CreateInput') &&
    ['id', 'createdAt', 'updatedAt'].includes(propertyName),
};

The callback receives FieldInfo (location, objectName, propertyName, propertyType, typeName). When shouldHideField is defined, it overrides @HideField(...) settings from field comments and legacy decorate rules.

Examples:

  • @HideField() same as @HideField({ output: true })
  • @HideField({ input: true, output: true })
  • @HideField({ match: 'UserCreate*Input' })
model User {
  id String @id @default(cuid())
  /// @HideField()
  password String
  /// @HideField({ output: true, input: true })
  secret String
  /// @HideField({ match: '@(User|Comment)Create*Input' })
  createdAt DateTime @default(now())
}

May generate classes:

@ObjectType()
export class User {
  @HideField()
  password: string;
  @HideField()
  secret: string;
  @Field(() => Date, { nullable: false })
  createdAt: Date;
}
@InputType()
export class UserCreateInput {
  @Field()
  password: string;
  @HideField()
  secret: string;
  @HideField()
  createdAt: Date;
}

Custom Decorators

Applying custom decorators requires configuration of generator.

// Legacy configuration, prefer config file
generator nestgraphql {
  fields_{namespace}_from = "module specifier"
  fields_{namespace}_input = true | false
  fields_{namespace}_output = true | false
  fields_{namespace}_model = true | false
  fields_{namespace}_defaultImport = "default import name" | true
  fields_{namespace}_namespaceImport = "namespace import name"
  fields_{namespace}_namedImport = true | false
}

Create configuration map in flatten style for {namespace}. Where {namespace} is a namespace used in field triple slash comment.

fields_{namespace}_from

Required. Name of the module, which will be used in import (class-validator, graphql-scalars, etc.) Type: string

fields_{namespace}_input

Means that it will be applied on input types (classes decorated by InputType) Type: boolean Default: false

fields_{namespace}_output

Means that it will be applied on output types (classes decorated by ObjectType), including models Type: boolean Default: false

fields_{namespace}_model

Means that it will be applied only on model types (classes decorated by ObjectType) Type: boolean Default: false

fields_{namespace}_defaultImport

Default import name, if module have no namespace. Type: undefined | string | true Default: undefined If defined as true then import name will be same as {namespace}

fields_{namespace}_namespaceImport

Import all as this namespace from module Type: undefined | string Default: Equals to {namespace}

fields_{namespace}_namedImport

If imported module has internal namespace, this allow to generate named import, imported name will be equal to {namespace}, see example of usage Type: boolean Default: false

Custom decorators example:

generator nestgraphql {
  fields_Validator_from = "class-validator"
  fields_Validator_input = true
}

model User {
  id Int @id
  /// @Validator.MinLength(3)
  name String
}

May generate following class:

import { InputType, Field } from '@nestjs/graphql';
import * as Validator from 'class-validator';

@InputType()
export class UserCreateInput {
  @Field(() => String, { nullable: false })
  @Validator.MinLength(3)
  name!: string;
}

Custom decorators can be applied on classes (models):

/// @NG.Directive('@extends')
/// @NG.Directive('@key(fields: "id")')
model User {
  /// @NG.Directive('@external')
  id String @id
}

generator nestgraphql {
  fields_NG_from = "@nestjs/graphql"
  fields_NG_output = false
  fields_NG_model = true
}

May generate:

import * as NG from '@nestjs/graphql';

@NG.Directive('@extends')
@NG.Directive('@key(fields: "id")')
export class User {
  @Field(() => ID, { nullable: false })
  @NG.Directive('@external')
  id!: string;

@FieldType()

Allow set custom GraphQL scalar type for field

To override scalar type in specific classes, you can use glob pattern match: string | string[] see outmatch for details.

model User {
  id Int @id
  /// @FieldType({ name: 'Scalars.GraphQLEmailAddress', from: 'graphql-scalars', input: true })
  email String
}

May generate following class:

import { InputType, Field } from '@nestjs/graphql';
import * as Scalars from 'graphql-scalars';

@InputType()
export class UserCreateInput {
  @Field(() => Scalars.GraphQLEmailAddress, { nullable: false })
  email!: string;
}

And following GraphQL schema:

scalar EmailAddress

input UserCreateInput {
  email: EmailAddress!
}

Same field type may be used in different models and it is not convenient to specify every time all options. There is a shortcut:

generator nestgraphql {
  fields_Scalars_from = "graphql-scalars"
  fields_Scalars_input = true
  fields_Scalars_output = true
}

model User {
  id Int @id
  /// @FieldType('Scalars.GraphQLEmailAddress')
  email String
}

The result will be the same. Scalars is the namespace here. Missing field options will merged from generator configuration.

@PropertyType()

Similar to @FieldType() but refer to TypeScript property (actually field too).

To override TypeScript type in specific classes, you can use glob pattern match: string | string[] see outmatch for details.

Example:

generator nestgraphql {
  fields_TF_from = "type-fest"
}

model User {
  id String @id
  /// @PropertyType('TF.JsonObject')
  data Json
}

May generate:

import * as TF from 'type-fest';

@ObjectType()
export class User {
  @Field(() => GraphQLJSON)
  data!: TF.JsonObject;
}

@Directive()

Allow attach @Directive decorator from @nestjs/graphql

GraphQL federation example:

/// @Directive({ arguments: ['@extends'] })
/// @Directive({ arguments: ['@key(fields: "id")'] })
model User {
  /// @Directive({ arguments: ['@external'] })
  id String @id
}

May generate:

@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID, { nullable: false })
  @Directive('@external')
  id!: string;
}

@ObjectType()

Allow rename type in schema and mark as abstract.

Example 1:

// schema.prisma
/// @ObjectType({ isAbstract: true })
model User {
  id Int @id
}
@ObjectType({ isAbstract: true })
export class User {}

Example 2:

// schema.prisma
/// @ObjectType('Human', { isAbstract: true })
model User {
  id Int @id
}
@ObjectType('Human', { isAbstract: true })
export class User {}

Using library in other generators

import { generate } from 'prisma-nestjs-graphql';

Similar Projects

Resources

TODO

  • CommentUncheckedUpdateManyWithoutAuthorNestedInput and CommentUpdateManyWithoutAuthorNestedInput are same
  • Add logic to detect view models and skip generation of mutation inputs/args for them https://github.com/unlight/prisma-nestjs-graphql/issues/248
  • dummy-createfriends.input.ts -> create-friends
  • check 'TODO FIXME'
  • rework test, use setup file

License

MIT License (c) 2026