Public Wiki45,239View on GitHub
Want prisma/prisma knowledge in your AI?

eslint-local-rules

This is the Prisma ORM monorepo — the complete source code for Prisma's Node.js/TypeScript ORM ecosystem, including the Prisma Client runtime, code generators (JS and TS), the Prisma CLI (with commands like generate, migrate, db push/pull, studio), driver adapters for multiple databases (PostgreSQL, MySQL/MariaDB, SQLite, SQL Server, PlanetScale, Neon, Turso/libSQL, Cloudflare D1), and the Prisma Migrate schema migration engine. It also includes Prisma Platform CLI integration for managed services like Accelerate and Pulse.

Tech Stack

JestZodPrismaPostgreSQLNext.jsTypeScriptExpress.jsMongoDBReactVitest

Key Features

  • Prisma Client Runtime & Query Engine
  • Type-Safe Client Code Generation
  • Prisma CLI
  • Database Driver Adapters
  • Prisma Migrate & Schema Engine
  • Prisma Studio
  • Query Plan Executor Server
  • Prisma Platform CLI (Accelerate & Pulse)
  • Matrix-Based Functional Test Suite
  • Prisma Config File Support

Entry Points

Start here when working with this codebase

Prisma CLI Main
packages/cli/src/bin.ts

Entry point for the `prisma` CLI binary. Bootstraps command parsing and dispatches to subcommands (generate, migrate, db, studio, etc.)

Start here when adding a new CLI command, modifying CLI behavior, or debugging CLI initialization

Prisma Client Runtime
packages/client/src/runtime/index.ts

Main export barrel for the Prisma Client runtime. Exposes PrismaClient class, query engine, extensions, and all runtime utilities

Start here when modifying how PrismaClient works at runtime, adding new client methods, or changing query execution

Client JS Generator Entry
packages/client-generator-js/src/generation/generateClient.ts

Orchestrates JS client code generation from DMMF. Produces the generated Prisma Client JS output files

Start here when changing what code gets generated for the JS client (e.g., new model methods, new generated types)

Client TS Generator Entry
packages/client-generator-ts/src/index.ts

Entry point for the TypeScript client generator that produces split-file TS output

Start here when modifying the TS generator output, adding new generated type files, or changing file splitting logic

Migrate Command Entry
packages/migrate/src/Migrate.ts

Core Migrate class that wraps the schema engine and provides migration operations (createMigration, applyMigrations, reset, etc.)

Start here when modifying migration behavior, adding new migration commands, or changing schema engine interaction

Internals Shared Utilities
packages/internals/src/index.ts

Barrel export for shared internal utilities: engine commands, generator handling, schema loading, CLI utilities

Start here when adding shared utilities consumed by CLI, migrate, or generators

Build System Entry
helpers/compile/build.ts

Build orchestration for all packages using esbuild. Manages compilation configs, watch mode, and plugin system

Start here when modifying how packages are built, adding esbuild plugins, or changing build output

Driver Adapter Utils
packages/driver-adapter-utils/src/index.ts

Shared types and utilities for all database driver adapters (pg, neon, d1, libsql, planetscale, etc.)

Start here when adding a new driver adapter or modifying the shared adapter interface

Client Engine Runtime
packages/client-engine-runtime/src/index.ts

Query plan interpreter, SQL generation, and transaction management for the client-side engine

Start here when modifying query plan execution, SQL generation, or transaction handling in the client engine

Config Loader
packages/config/src/index.ts

Loads and validates prisma.config.ts configuration files

Start here when adding new config options or changing how prisma.config.ts is parsed

Query Plan Executor Server
packages/query-plan-executor/src/server/server.ts

HTTP server that exposes query execution, transaction management, and health check endpoints

Start here when adding new server endpoints or modifying query execution API

ESLint Local Rules
eslint-local-rules/index.js

Aggregates and exposes custom ESLint rules as a plugin for the monorepo

Start here when adding new custom lint rules for codebase conventions

Client Default Export
packages/client/default.js

Clean export interface for the Prisma ORM client package

Start here when modifying what gets exported from the @prisma/client package

DMMF Types
packages/dmmf/src/index.ts

Prisma DMMF (Data Model Meta Format) types and conversion utilities

Start here when modifying the data model representation or adding new DMMF fields

How to Make Changes

Common modification patterns for this codebase

Add a new CLI command

1
packages/cli/src/CLI.ts

Register the new command in the CLI command map. Add an entry to the commands object with the command name as key and the command class as value

Pattern: See how 'generate', 'validate', 'format' commands are registered in the CLI constructor's command map

2
packages/cli/src/NewCommand.ts

Create a new command file implementing the Command interface. Export a class with `parse()` method for argument parsing and a `run()` method for execution logic

Pattern: Follow the structure of packages/cli/src/Init.ts which implements constructor with help text, parse() for args, and the main execution logic

3
packages/cli/src/bin.ts

If the command needs special bootstrapping or early initialization, add it to the dispatch logic in the bin entry point

Pattern: See how 'studio' and 'platform' commands are handled with special cases in packages/cli/src/bin.ts

4
packages/cli/src/__tests__/commands.test.ts

Add tests for the new command covering argument parsing, help output, and core execution paths

Pattern: Follow test patterns in packages/cli/src/__tests__/ directory where each command has corresponding test files

Conventions to follow:

Commands are classes with a static `new()` factory or constructor patternEach command defines its own help text as a string propertyUse @prisma/internals for shared utilities like schema loading and engine commandsError handling uses the HelpError class for user-facing argument errorsCommands return a string result that gets printed to stdout

Add a new Prisma Client query method or operation

1
packages/client/src/runtime/core/model/applyModel.ts

Add the new operation to the model-level API. Register the method name and wire it to the query pipeline

Pattern: See how findMany, findUnique, create, update, delete operations are registered and dispatched in this file

2
packages/client/src/runtime/core/request/PrismaActionType.ts

Add the new action type to the PrismaAction union type so it's recognized throughout the runtime

Pattern: See existing action types like 'findUnique', 'findMany', 'create', 'update', 'delete', 'aggregate' in this file

3
packages/client-common/src/types/index.ts

Add any new shared types needed for the operation's arguments and return types

Pattern: Follow existing type definitions for operations like FindManyArgs, CreateArgs patterns in packages/client-common/src/types/

4
packages/client-generator-js/src/generation/generateClient.ts

Update the JS code generator to emit the new method signature in generated client code

Pattern: See how existing model methods are generated by tracing how 'findMany' appears in the generation pipeline

5
packages/client-generator-ts/src/index.ts

Update the TS code generator to emit proper TypeScript types for the new method

Pattern: Follow how existing operations produce type definitions in the TS generator output

6
packages/client/tests/functional/_newOperation/tests.ts

Create a new functional test directory with test matrix and test cases covering all providers

Pattern: Follow the structure of packages/client/tests/functional/findMany/tests.ts which defines test matrix, prisma schema, and test cases

Conventions to follow:

All query operations go through the request pipeline in packages/client/src/runtime/core/request/Operations must be typed in both the runtime and the generated client outputFunctional tests use a matrix pattern to test across all database providers (postgres, mysql, sqlite, etc.)The DMMF types in packages/dmmf/ may need updating if the operation introduces new schema concepts

Add a new database driver adapter

1
packages/driver-adapter-utils/src/index.ts

Review and potentially extend the shared adapter interface (Queryable, DriverAdapter, TransactionContext types) if the new database requires additional capabilities

Pattern: See the existing interface definitions in packages/driver-adapter-utils/src/types.ts for the contract all adapters must implement

2
packages/adapter-newdb/src/index.ts

Create a new adapter package directory (packages/adapter-newdb/) with src/index.ts as the entry point. Implement the DriverAdapter interface with queryRaw, executeRaw, and transaction methods

Pattern: Follow packages/adapter-pg/src/pg.ts which implements the full adapter interface for PostgreSQL: connection handling, query execution, type conversion, and transaction support

3
packages/adapter-newdb/src/conversion.ts

Create type conversion utilities that map between the database's native types and Prisma's internal ColumnType enum

Pattern: Follow packages/adapter-pg/src/conversion.ts which maps PostgreSQL OIDs to Prisma column types and handles value serialization/deserialization

4
packages/adapter-newdb/package.json

Create package.json with proper name (@prisma/adapter-newdb), dependencies on @prisma/driver-adapter-utils, and the database driver package

Pattern: Copy the structure from packages/adapter-pg/package.json and adjust the name, description, and database-specific dependencies

5
packages/adapter-newdb/tsconfig.json

Create tsconfig.json extending the monorepo base config

Pattern: Copy from packages/adapter-pg/tsconfig.json

6
packages/client/tests/functional/_utils/providers.ts

Register the new provider in the test matrix so functional tests can run against it

Pattern: See how existing providers (postgresql, mysql, sqlite, mongodb, cockroachdb, sqlserver) are defined in the test utilities

Conventions to follow:

All adapters implement the DriverAdapter interface from @prisma/driver-adapter-utilsType conversion between database-native types and Prisma ColumnType is mandatoryAdapters must handle both regular queries and interactive transactionsError handling should wrap database-specific errors into Prisma-compatible error objectsThe adapter package name follows the pattern @prisma/adapter-{dbname}

Add a new query plan executor endpoint

1
packages/query-plan-executor/src/server/schemas.ts

Define the request/response Zod schemas for the new endpoint including method, path, body schema, and response schema

Pattern: Follow how POST /query and POST /transaction/start endpoints define their schemas with Zod in this file (querySchema, startTransactionSchema, etc.)

2
packages/query-plan-executor/src/server/server.ts

Add the route handler for the new endpoint. Register it with the HTTP server, parse the request body using the schema, call the appropriate application logic, and return the response

Pattern: Follow how the POST /query handler validates the body against querySchema, calls app.query(), and returns JSON. See the route registration pattern with method + path matching

3
packages/query-plan-executor/src/server/app.ts

Add the business logic method to the application class that the route handler will call

Pattern: Follow how the existing query() and startTransaction() methods are implemented in the app layer, delegating to the engine/adapter

Conventions to follow:

All request/response shapes are defined as Zod schemas in schemas.tsRoute handlers validate input with Zod before processingTransaction endpoints use :txId path parameter for transaction identificationAll endpoints return JSON responsesHealth check at GET /health must always remain available

Add a new Platform CLI subcommand (e.g., under prisma platform)

1
packages/cli/src/platform/newFeature/newCommand.ts

Create a new command file in the platform directory. Export a command object with name, description, and action handler that calls the management API

Pattern: Follow packages/cli/src/platform/accelerate/enable.ts which defines a command with GraphQL mutation, argument parsing, authentication check, and formatted output

2
packages/cli/src/platform/index.ts

Register the new subcommand in the platform command registry so it's discoverable by the CLI dispatcher

Pattern: See how accelerate, pulse, and environment commands are registered in the platform index

3
packages/cli/src/management-api/auth.ts

If the command requires authentication, reuse the existing auth flow. If it needs new API scopes or tokens, extend the auth module

Pattern: See how packages/cli/src/platform/accelerate/enable.ts uses the auth utilities for token management and the OAuth callback at GET /auth/callback

Conventions to follow:

Platform commands use GraphQL mutations/queries to communicate with the Prisma management APIAuthentication is handled via OAuth 2.0 with token cachingCommands should provide clear success/error output with formatting helpersEach platform feature (accelerate, pulse, etc.) gets its own subdirectory under packages/cli/src/platform/

Add a new Prisma Client extension

1
packages/client/src/runtime/core/extensions/index.ts

Define the extension point. Add the new extension type to the extension registry and define its interface

Pattern: See how existing extension types (model, client, query, result) are defined and registered in the extensions module

2
packages/client/src/runtime/core/extensions/applyExtensions.ts

Implement the extension application logic that merges user-provided extension callbacks into the client prototype chain

Pattern: Follow how model extensions are applied by wrapping the original methods and calling the extension callback in the middleware chain

3
packages/client/tests/functional/extensions/

Add functional tests for the new extension type covering registration, execution, and interaction with other extensions

Pattern: Follow the test structure in packages/client/tests/functional/ where each feature has a directory with tests.ts and prisma/ schema files

Conventions to follow:

Extensions use the $extends() API on PrismaClientExtension types are: model, client, query, resultExtensions compose via prototype chain wrapping, not mutationType safety for extensions is generated in the client output

Add a new migration command (e.g., prisma migrate newAction)

1
packages/migrate/src/commands/MigrateNewAction.ts

Create a new command class implementing the migration action. Include help text, argument definitions, and the main execution logic that calls the Migrate class

Pattern: Follow packages/migrate/src/commands/MigrateDev.ts which defines a command with help text, parse() for arguments, and calls this.migrate methods for schema engine interaction

2
packages/migrate/src/Migrate.ts

Add the new migration operation method to the Migrate class. This method should interact with the schema engine via the engine RPC interface

Pattern: See how createMigration(), applyMigrations(), and reset() methods are implemented in packages/migrate/src/Migrate.ts, each making RPC calls to the schema engine

3
packages/cli/src/CLI.ts

Register the new migrate subcommand in the CLI command map under the 'migrate' namespace

Pattern: See how 'migrate dev', 'migrate deploy', 'migrate reset' are registered as subcommands in the CLI

4
packages/migrate/src/__tests__/MigrateNewAction.test.ts

Add integration tests for the new migration command

Pattern: Follow packages/migrate/src/__tests__/MigrateDev.test.ts which tests command execution with various schema states and argument combinations

Conventions to follow:

Migration commands interact with the schema engine via RPC methods on the Migrate classCommands must handle the migration lock to prevent concurrent migrationsUser-facing output uses formatted prompts and colored outputMigration state is tracked in the _prisma_migrations table and the migrations/ directory

Add a new custom ESLint rule

1
eslint-local-rules/src/newRule.ts

Create the rule implementation file with meta (type, docs, schema) and create() function returning AST visitor methods

Pattern: Follow existing rule files in eslint-local-rules/src/ which export an object with meta and create properties following the ESLint rule API

2
eslint-local-rules/index.js

Import and register the new rule in the rules object exported by this module so it's available as 'local-rules/new-rule-name'

Pattern: See how existing rules are imported and added to the module.exports.rules object in this file

3
eslint.config.cjs

Enable the new rule in the ESLint configuration with the desired severity (error/warn) and any rule options

Pattern: See how existing local-rules/* are configured in the rules section of eslint.config.cjs

Conventions to follow:

Rule names use kebab-case and are prefixed with 'local-rules/' when referenced in configRules must export meta with type ('problem' | 'suggestion' | 'layout'), docs, and optional schemaThe create() function receives context and returns an AST visitor objectRules are aggregated in eslint-local-rules/index.js as a flat object

Coding Conventions

Standards and patterns used in this codebase

Package Management

Enforce pnpm as the only allowed package manager across the monorepo. A preinstall script checks the user agent and exits with an error if npm or yarn is used.

const wantedPM = 'pnpm'; if (usedPM !== wantedPM) { console.warn(`Use "${wantedPM}" ...`); process.exit(1); }
scripts/only-allow-pnpm.js
Build System

Use esbuild for building packages with a centralized build orchestration layer. Build configs support both CommonJS and ESM output formats, with watch mode support and plugin integration. Adapter and unbundled configs are generated via shared helper functions.

export function getAdapterBuildConfig(options) { return [{ name: pkg.name, bundle: true, emitTypes: true, format: ['cjs', 'esm'] }] }
helpers/compile/build.tshelpers/compile/configs.ts
Utility Design

Small, single-purpose utility functions are placed in individual files with clear names. Each utility file exports one focused function (get, handle, merge, pipe, range, record) following a functional programming style with generics for type safety.

export function get<T extends Record<string, unknown>, K extends keyof T>(object: T, key: K): T[K] { return object[key] }
helpers/blaze/get.tshelpers/blaze/handle.tshelpers/blaze/merge.tshelpers/blaze/pipe.tshelpers/blaze/range.tshelpers/blaze/record.ts
Error Handling

Use wrapper functions that catch exceptions and return them as values rather than throwing, enabling result-or-error pattern handling. Functions return either the successful result or the caught exception typed appropriately.

export function handle<T, E = Error>(fn: () => T): T | E { try { return fn() } catch (e) { return e as E } }
helpers/blaze/handle.ts
Linting

Use custom ESLint local rules to enforce project-specific conventions beyond standard linting. These are defined in a dedicated eslint-local-rules package and registered in the root ESLint config alongside standard TypeScript and import plugins.

module.exports = { 'rule-name': { meta: { type: 'problem', ... }, create(context) { ... } } }
eslint-local-rules/index.jseslint.config.cjs
TypeScript

Prefer strict TypeScript with generics and type-safe patterns. Utility functions use generic type parameters with constraints (extends Record, extends keyof) to ensure compile-time type safety. Async variants are provided alongside sync versions where applicable.

export function pipe<T>(value: T): { through: <R>(fn: (value: T) => R) => ReturnType<typeof pipe<R>>; get: () => T }
helpers/blaze/pipe.tshelpers/blaze/get.ts
Testing

Benchmarks are discovered and executed via a centralized script that scans for .bench.ts files across packages. Functional tests use a matrix-based approach to run across all database providers. E2E tests validate real project setups (Next.js, bundlers).

const benchmarkFiles = glob.sync('**/*.bench.ts', { cwd: packagesDir }); for (const file of benchmarkFiles) { await run(file) }
scripts/bench.ts
Module Structure

The monorepo uses a layered package architecture with clear dependency boundaries: common/shared packages (client-common, driver-adapter-utils, client-runtime-utils) provide shared types and utilities, while feature packages depend on them. Generators, runtime, and engine concerns are separated into distinct packages.

packages/client-common (shared types) -> packages/client-generator-js (JS codegen) -> packages/client/src/runtime (runtime)
helpers/compile/configs.ts
Code Style

Use functional programming patterns: reduce for building objects, composition via pipe, immutable transformations. Avoid classes for utilities; prefer plain exported functions. Use arrow functions for inline callbacks and named function declarations for exports.

export function merge<T extends object>(objects: T[]): T { return objects.reduce((acc, obj) => ({ ...acc, ...obj }), {} as T) }
helpers/blaze/merge.tshelpers/blaze/record.tshelpers/blaze/range.ts