Skip to content

marcalexiei/eslint-plugin-zod

Repository files navigation

eslint-plugin-zod

CI Code style: prettier Lint: eslint npm version issues

ESLint plugin that adds custom linting rules to enforce best practices when using Zod

Rules

zod and zod-mini have distinct API surfaces. This plugin is primarily built for zod, so some rules are exclusive to zod and not available for zod-mini.

💼 Configurations enabled in.
✅ Set in the recommended configuration.
✔️ Set in the recommendedMini configuration.
🔧 Automatically fixable by the --fix CLI option.
💡 Manually fixable by editor suggestions.
❌ Deprecated.

Universal rules (zod & zod-mini)

Name                          Description 💼 🔧 💡
consistent-import Enforce a consistent import style for Zod 🔧
consistent-import-source Enforce consistent source from Zod imports 💡
consistent-object-schema-type Enforce consistent usage of Zod schema methods 💡
no-any-schema Disallow usage of z.any() in Zod schemas ✅ ✔️ 💡
no-empty-custom-schema Disallow usage of z.custom() without arguments
no-unknown-schema Disallow usage of z.unknown() in Zod schemas
prefer-meta Enforce usage of .meta() over .describe() ✅ ✔️ 🔧
prefer-namespace-import Enforce importing zod as a namespace import (import * as z from 'zod') 🔧
require-brand-type-parameter Require type parameter on .brand() functions ✅ ✔️ 💡
require-error-message Enforce that custom refinements include an error message ✅ ✔️ 🔧
require-schema-suffix Require schema suffix when declaring a Zod schema ✅ ✔️
schema-error-property-style Enforce consistent style for error messages in Zod schema validation (using ESQuery patterns)

zod exclusive rules

Name                             Description 💼 🔧 💡
array-style Enforce consistent Zod array style 🔧
no-number-schema-with-int Disallow usage of z.number().int() as it is considered legacy 🔧
no-optional-and-default-together Disallow using both .optional() and .default() on the same Zod schema 🔧
no-string-schema-with-uuid Disallow usage of z.string().uuid() in favor of the dedicated z.uuid() schema 🔧
no-throw-in-refine Disallow throwing errors directly inside Zod refine callbacks
prefer-enum-over-literal-union Prefer z.enum() over z.union() when all members are string literals. 🔧
prefer-meta-last Enforce .meta() as last method 🔧
prefer-string-schema-with-trim Enforce z.string().trim() to prevent accidental leading/trailing whitespace 🔧

Installation

Install eslint and eslint-plugin-zod using your preferred package manager:

npm i --save-dev eslint eslint-plugin-zod
yarn add --dev eslint eslint-plugin-zod
pnpm add --save-dev eslint eslint-plugin-zod

Configuration

  1. Import the plugin

    import eslintPluginZod from 'eslint-plugin-zod';
  2. Add recommended config to your ESLint setup

    eslintPluginZod.configs.recommended,

Here’s a minimal example using the flat config format:

// eslint.config.js
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js';
import eslintPluginZod from 'eslint-plugin-zod';

export default defineConfig(
  eslint.configs.recommended,
  eslintPluginZod.configs.recommended,
);

Zod peer dependency version

eslint-plugin-zod is designed for projects that use zod@^4. While the plugin analyzes Zod schemas in your code, it doesn’t import or depend on Zod at runtime. To document this relationship without forcing installation, Zod is declared as an optional peer dependency in the plugin’s package.json.

If your project uses Zod v4, the plugin will automatically lint your schemas. If you’re not using Zod (for example, in a separate ESLint workspace), you don’t need to install it.

About

ESLint plugin that adds custom linting rules to enforce best practices when using Zod

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Contributors