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
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
packages/cli/src/bin.tsEntry 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
packages/client/src/runtime/index.tsMain 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
packages/client-generator-js/src/generation/generateClient.tsOrchestrates 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)
packages/client-generator-ts/src/index.tsEntry 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
packages/migrate/src/Migrate.tsCore 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
packages/internals/src/index.tsBarrel 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
helpers/compile/build.tsBuild 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
packages/driver-adapter-utils/src/index.tsShared 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
packages/client-engine-runtime/src/index.tsQuery 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
packages/config/src/index.tsLoads and validates prisma.config.ts configuration files
Start here when adding new config options or changing how prisma.config.ts is parsed
packages/query-plan-executor/src/server/server.tsHTTP 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/index.jsAggregates and exposes custom ESLint rules as a plugin for the monorepo
Start here when adding new custom lint rules for codebase conventions
packages/client/default.jsClean export interface for the Prisma ORM client package
Start here when modifying what gets exported from the @prisma/client package
packages/dmmf/src/index.tsPrisma 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
packages/cli/src/CLI.tsRegister 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
packages/cli/src/NewCommand.tsCreate 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
packages/cli/src/bin.tsIf 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
packages/cli/src/__tests__/commands.test.tsAdd 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:
Add a new Prisma Client query method or operation
packages/client/src/runtime/core/model/applyModel.tsAdd 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
packages/client/src/runtime/core/request/PrismaActionType.tsAdd 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
packages/client-common/src/types/index.tsAdd 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/
packages/client-generator-js/src/generation/generateClient.tsUpdate 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
packages/client-generator-ts/src/index.tsUpdate 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
packages/client/tests/functional/_newOperation/tests.tsCreate 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:
Add a new database driver adapter
packages/driver-adapter-utils/src/index.tsReview 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
packages/adapter-newdb/src/index.tsCreate 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
packages/adapter-newdb/src/conversion.tsCreate 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
packages/adapter-newdb/package.jsonCreate 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
packages/adapter-newdb/tsconfig.jsonCreate tsconfig.json extending the monorepo base config
Pattern: Copy from packages/adapter-pg/tsconfig.json
packages/client/tests/functional/_utils/providers.tsRegister 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:
Add a new query plan executor endpoint
packages/query-plan-executor/src/server/schemas.tsDefine 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.)
packages/query-plan-executor/src/server/server.tsAdd 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
packages/query-plan-executor/src/server/app.tsAdd 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:
Add a new Platform CLI subcommand (e.g., under prisma platform)
packages/cli/src/platform/newFeature/newCommand.tsCreate 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
packages/cli/src/platform/index.tsRegister 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
packages/cli/src/management-api/auth.tsIf 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:
Add a new Prisma Client extension
packages/client/src/runtime/core/extensions/index.tsDefine 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
packages/client/src/runtime/core/extensions/applyExtensions.tsImplement 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
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:
Add a new migration command (e.g., prisma migrate newAction)
packages/migrate/src/commands/MigrateNewAction.tsCreate 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
packages/migrate/src/Migrate.tsAdd 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
packages/cli/src/CLI.tsRegister 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
packages/migrate/src/__tests__/MigrateNewAction.test.tsAdd 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:
Add a new custom ESLint rule
eslint-local-rules/src/newRule.tsCreate 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
eslint-local-rules/index.jsImport 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
eslint.config.cjsEnable 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:
Coding Conventions
Standards and patterns used in this codebase
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); }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'] }] }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] }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 } }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) { ... } } }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 }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) }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)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) }