Open-Source Wikis

/

Prisma

/

How to contribute

/

Patterns and conventions

prisma/prisma

Patterns and conventions

Coding conventions, style rules, and cross-cutting patterns enforced in this repo. Most of this is codified in AGENTS.md and eslint.config.cjs plus eslint-local-rules/.

File names

  • kebab-case for new file names: query-utils.ts, filter-operators.test.ts. Existing PascalCase files (Migrate.ts, ClientEngine.ts) stay as they are unless renamed for another reason.

Imports

  • Avoid creating new barrel files (index.ts that re-export from sibling modules). Import from the source directly:

    // ✅ Preferred
    
    // ❌ Avoid for new code
    import { foo } from './utils';
    import { foo } from './utils/query-utils';

    If utils/index.ts already exists, keep using it for consistency with surrounding code.

  • Use type-only imports (import type { … }) when the symbol is only used in type position. The build's tree-shaking depends on this.

  • The simple-import-sort ESLint plugin enforces a deterministic import order.

Comments

From AGENTS.md:

Inline code comments can be broadly categorized as answering one of three questions:

  • What does this code do? — never write these. They duplicate the code and rot.
  • Why was this code written (in this particular way or at all)? — this is what inline comments are for. Use them for context, GitHub issue references, decision rationale.
  • How does this code work? — these should be exceedingly rare. Prefer rewriting to be clear, unless the complexity is intrinsic (algorithm names, references to papers, external systems).

Documentation comments on exported items are encouraged. Use them to describe the contract of the function/class/method, not the internal implementation details.

Class members

Prefer native JavaScript private syntax (#field, #method()) over the TypeScript private keyword. Native private fields are real runtime privacy; the TypeScript private keyword is only erased by the type checker.

"Wasm", not "WASM"

The official spelling is Wasm. There are stale "WASM" usages in the codebase, but they're considered errors. Fix them whenever you incidentally touch the surrounding code.

Error handling

Across the runtime, errors flow through several stages before reaching user code. The pipeline is:

  1. Adapter level — the underlying driver throws (e.g., pg's error.code === '23505').
  2. convertDriverError() — each adapter (packages/adapter-pg/src/errors.ts, packages/adapter-mysql/src/errors.ts, …) maps the DB code to a MappedError kind from @prisma/driver-adapter-utils.
  3. rethrowAsUserFacing()packages/client-engine-runtime/src/user-facing-error.ts maps MappedError kinds to public Prisma error codes (P2xxx).
  4. Client surface — the user sees PrismaClientKnownRequestError (with .code, .meta, .message) or PrismaClientUnknownRequestError.

To add a new error mapping:

  1. Add the kind to MappedError in packages/driver-adapter-utils/src/types.ts.
  2. Map the database error code in each adapter that can produce it.
  3. Add Prisma code mapping in getErrorCode() and message in renderErrorMessage() (packages/client-engine-runtime/src/user-facing-error.ts).

Error code conventions:

  • P2000–P2037 are documented in the public error reference.
  • P2038PrismaClientInitializationError from ClientEngine when no driver adapter is configured.
  • P2039 — fallback code for unmapped database-specific driver-adapter errors. The format is Database error. Code: <originalCode>. Message: <originalMessage>. Used so unknown DB errors show up as HTTP 400 from the query plan executor instead of 500 (Accelerate strips 500s).
  • Pick the next available code (P2040, …) for new additions and document it in AGENTS.md.

Raw queries ($executeRaw, $queryRaw) use a different path — rethrowAsUserFacingRawError() always returns P2010 with the format Raw query failed. Code: <originalCode>. Message: <originalMessage>.

Asserting on errors in tests

From AGENTS.md:

// ✅ Preferred — works across realms (e.g., generated client in subdirectory)
expect(result.name).toBe('PrismaClientKnownRequestError');
expect(result.code).toBe('P2002');

// ❌ Brittle — instanceof check fails when the constructor comes from a different realm
expect(result).toBeInstanceOf(PrismaClientKnownRequestError);

Tests

  • Test files use *.test.ts (Jest) or *.vitest.ts (Vitest where the package is mid-migration). Both are excluded from build output by esbuild config.
  • Test files live alongside source files (under __tests__/ or directly next to the source — package-by-package convention).
  • Inline snapshots are sensitive to formatting. Prefer concise expectations unless the exact message is part of the contract.
  • Functional generated clients in packages/client/tests/functional/**/.generated import packages/client/runtime/client.js directly. Runtime changes in src/runtime may need corresponding bundle rebuilds before functional tests pick them up.

Schema fixtures

  • Test fixtures live in packages/<pkg>/src/__tests__/fixtures (most packages) and packages/<pkg>/fixtures (a few).
  • Many fixtures pair a schema with a prisma.config.ts (sometimes multiple variants, e.g., invalid-url.config.ts next to invalid-url.prisma).
  • Tests swap configs with ctx.setConfigFile(name) from __helpers__/prismaConfig.ts. Reset is automatic between tests.

Cross-cutting hygiene

  • Stay ASCII unless a file already uses Unicode.
  • Keep AGENTS.md updated when you discover something new about the codebase. It's the canonical agent-facing knowledge base; staleness costs everyone.
  • Build from root after multi-package changes: pnpm build (or pnpm dev) from the repo root respects Turborepo's dependency graph. Per-package builds can miss upstream changes.

ESLint local rules

eslint-local-rules/ defines project-specific rules. They're loaded by the eslint-plugin-local-rules plugin from the root eslint.config.cjs. Read them as a reference for "what does Prisma's own code review actually enforce".

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Patterns and conventions – Prisma wiki | Factory