Plugins

ESLint

Static Better Drizzle guardrails for IDE and CI feedback.

@better-drizzle/eslint is the static surface for Better Drizzle guardrails. It mirrors the directly-checkable subset of @better-drizzle/rules and is meant for editor feedback and CI, not runtime enforcement.

Install

npm install -D eslint @typescript-eslint/parser @better-drizzle/eslint
pnpm add -D eslint @typescript-eslint/parser @better-drizzle/eslint
yarn add -D eslint @typescript-eslint/parser @better-drizzle/eslint
bun add -d eslint @typescript-eslint/parser @better-drizzle/eslint

Flat Config

import parser from '@typescript-eslint/parser';
import betterDrizzle from '@better-drizzle/eslint';

export default [
	{
		files: ['**/*.{ts,tsx,mts,cts}'],
		languageOptions: {
			parser,
			sourceType: 'module',
		},
		plugins: {
			'better-drizzle': betterDrizzle,
		},
		rules: {
			...betterDrizzle.configs.recommended[0].rules,
		},
	},
];

The package also exports safe, recommended, and strict flat-config arrays.

What It Checks

The ESLint plugin only analyzes direct and obvious Better Drizzle call sites such as:

  • client.users.findMany(...)
  • client.repository('users').updateMany(...)
  • client.$rawUnsafe(...)
  • client.users.$withoutPlugins().findMany(...)

It does not try to infer transaction state, runtime meta, dialect-specific behavior, or complex wrapper functions.

Supported Rules

Every rule accepts the same boolean/severity shorthand as the runtime plugin where applicable:

  • true => error
  • false => off
  • 'warn' | 'error' | 'off'
  • an object with level plus rule-specific options

Destructive Writes

RuleOptions
noDeleteManyWithoutWherenone
noUpdateManyWithoutWherenone
noDeleteWithoutWherenone
noUpdateWithoutWherenone
noEmptyWhereoperations, treatUndefinedAsEmpty, treatEmptyAndOrAsEmpty

Reads and Pagination

RuleOptions
noUnboundedFindManyallowWithWhere, allowWithLimit, allowWithTake, allowSmallStaticModels
requireExplicitLimitoperations
maxLimitvalue, applyTo
requireOrderByForLimitnone
requireOrderByForPaginationnone
requireOrderByForCursornone
requireStableOrderByForCursorrequirePrimaryKeyInOrderBy

Includes and Locks

RuleOptions
maxIncludeDepthvalue
maxIncludeRelationsvalue
noLockWithIncludenone
noInvalidLockCombinationnone
requireOrderByForSkipLockednone
requireLimitForSkipLockednone

Raw SQL

RuleOptions
noRawUnsafenone
requireRawCommentminLength
requireRawTimeoutdefaultTimeoutMs, maxTimeoutMs
noRawMutationallow

Sensitive Fields and Plugin Bypass

RuleOptions
noSensitiveSelectallowWithSensitive, withSensitiveArg
requireExplicitSensitiveAccessReasonwithSensitiveArg, reasonArg
noWithoutPluginsnone
noPluginBypassWithoutReasonreasonArg

Presets

  • safe
  • recommended
  • strict

These presets mirror the statically-safe subset of @better-drizzle/rules. Runtime-only rules such as tenant context, transaction state, and dialect handling remain in @better-drizzle/rules.

Example

import { recommended } from '@better-drizzle/eslint';

export default [
	...recommended,
];

Boundary

Use @better-drizzle/eslint when you want immediate feedback in Zed, VS Code, or CI. Use @better-drizzle/rules when you need runtime enforcement inside the actual Better Drizzle client.

On this page