Comprehensive ESLint configuration used across Zimbra JavaScript and TypeScript projects.
This package bundles a set of shareable ESLint configs and rule customizations so teams can apply a consistent linting standard across apps and libraries.
- Overview
- Quick start
- Installation
- Prettier integration (important)
- When should I integrate this?
- What problem will it resolve?
- Usage examples
- ESLint Flat Config example (eslint.config.mjs)
- Exports & configs
- Architecture & rule organization
- Scripts
- Publishing
- Contributing
- License
- Support
This package provides:
- A base ESLint config (default export) customized or adapted specifically for Zimbra projects.
- A TypeScript-focused config (exported at
./src/typescript.js). - Curated configs in
src/configs/for special cases (automation, core-js, locale JSON, etc.). - Rule definitions and small custom plugins under
src/rules/, includingcustom-rulesused internally.
- Install the package as a dev dependency in your project.
- Install
eslint(peer dependency). - Extend
@zimbra/eslint-configin your ESLint configuration.
Install the config and core peer dependency:
npm install --save-dev @zimbra/eslint-config eslintIf you're using TypeScript:
npm install --save-dev @zimbra/eslint-config eslint @typescript-eslint/parser @typescript-eslint/eslint-pluginThis package ships many commonly-used ESLint plugins and configs as regular dependencies, so in most cases a consumer project does not need to manually install every plugin listed below. However, the package lists core items such as eslint and @typescript-eslint/eslint-plugin as peer dependencies — you must install those in your project. If you rely on the TypeScript export, also install @typescript-eslint/parser and typescript.
Typical plugins/configs that are included or commonly required by the configs in this package:
eslint-plugin-reacteslint-plugin-react-hookseslint-plugin-importeslint-config-prettierandeslint-plugin-prettiereslint-plugin-i18n-json
If you publish or use a custom registry where dependency resolution differs, you may need to install additional plugins in the consumer project. The safest minimal installs for a consumer are shown in the Installation section above (eslint + TypeScript plugin when relevant).
This config integrates Prettier via eslint-config-prettier and eslint-plugin-prettier to avoid conflicting rules and to report formatting issues through ESLint. Prettier rules will therefore be applicable to a consumer's code when they run ESLint with this config.
Recommendation: install prettier in consumer projects if you want code formatted or want eslint --fix to apply Prettier-based changes. Example:
npm install --save-dev prettierIf a consumer prefers to keep Prettier separate from ESLint (for example, running Prettier via editor integration only), the config will still disable conflicting ESLint rules thanks to eslint-config-prettier so you won't get duplicate or contradictory diagnostics.
Integrate @zimbra/eslint-config into a project when:
- You want consistent linting rules across multiple Zimbra repositories or teams.
- You are starting a new JavaScript/TypeScript project and want a tested baseline of rules (React/Prettier/i18n/import rules already wired).
- You want to centralize and reuse custom rules implemented by Zimbra (for patterns like
no-direct-memoize). - You want a config that is compatible with ESLint v9+ and the Flat Config approach used by modern tooling.
Integration is low-risk: drop-in extend the base or TypeScript export in your ESLint config and run eslint to see the issues the rules detect.
Using a centralized, shared ESLint config resolves several common problems:
- Inconsistent code style and rule application across teams and projects.
- Diverging local rule sets that make code reviews harder and increase cognitive load when switching repos.
- Missing project-specific checks for important areas like i18n, import ordering, React best practices, and automation/test patterns.
- Redundant or conflicting rule configurations — this package integrates Prettier properly and disables conflicting ESLint rules to avoid duplicate diagnostics.
Adopting this config helps maintain code quality, reduces time spent configuring tooling in each repository, and provides a shared place to evolve rules and custom checks.
If your project uses ESLint v9+ with the Flat Config (eslint.config.mjs / eslint.config.cjs), import the named config blocks exported by this package and add them to your exported array. Example JS project:
// eslint.config.mjs
import { coreJsConfig, customConfig } from "@zimbra/eslint-config";
export default [
coreJsConfig,
customConfig,
// Add local overrides or additional blocks here
{
files: ["**/*.js", "**/*.jsx"],
rules: {
// local rule overrides
}
}
];Example React project with i18n support:
// eslint.config.mjs
import { coreJsConfig, customConfig, reactConfig, preactI18nConfig } from "@zimbra/eslint-config";
export default [
coreJsConfig,
customConfig,
reactConfig,
preactI18nConfig,
{
files: ["**/*.jsx"],
// local React overrides (if needed)
}
];TypeScript project using the package TypeScript export:
// eslint.config.mjs
import { coreJsConfig } from "@zimbra/eslint-config";
import typescriptConfig from "@zimbra/eslint-config/typescript";
export default [
coreJsConfig,
typescriptConfig,
{
files: ["**/*.ts", "**/*.tsx"],
// local TypeScript overrides (if needed)
}
];Notes:
- Ensure your project has
type: "module"inpackage.jsonor use the.mjsextension for the config file so Node treats it as ESM. - Install peer dependencies (
eslint,@typescript-eslint/*,prettier) in the consumer project as described in the Installation section. - The exported config blocks (
coreJsConfig,customConfig, etc.) are objects that represent a single ESLint config block — add them directly to your config array without spreading.
coreJsConfig— Base JavaScript config with ESLint recommended rules, import rules, security, and style rules.customConfig— Custom Zimbra rules (includesno-direct-memoizeand other custom patterns).reactConfig— React and React Hooks rules (includes plugin setup and recommended rules).preactI18nConfig— Preact i18n rules and configuration (requiresESLINT_INTL_PATHenvironment variable or defaults tosrc/intl).prettierConfig— Prettier integration (formatting rules and conflict resolution).automationConfig— Automation/TestCafe rules for test files.localeJsonConfig— i18n JSON validation rules.
./typescript->src/typescript.js(TypeScript-focused config — exportstsEslintConfig)
The package follows a modular structure:
src/rules/— Individual rule modules (react, style, security, import, etc.) that define which ESLint rules are enabled and their severity levels.src/configs/— Config modules that combine related rules and plugins into focused, reusable blocks. Each config handles a specific concern (e.g., React, i18n, Prettier, automation).src/index.js— Exports the themed configs for use in consumer projects.src/typescript.js— TypeScript-specific config export.
Rule details and descriptions have moved to RULES.md. That file contains a complete list of rule modules and plain-language explanations of what each rule enforces or why a rule is disabled. It also reflects the latest updates in this branch, including converting numeric rule severity values (0/1/2) into explicit words (off, warn, error) for src/rules/style.js and src/rules/security.js rules. See RULES.md in the repo root for the authoritative list and examples.
Custom rules are defined in src/rules/custom-rules/:
no-direct-memoize.js— Prevents direct wrapping of components in React.memo without considering performance implications. Use memoization only when genuinely needed.
This repository provides convenience scripts in package.json that are useful for developing the config itself:
npm run lint— runseslint srcnpm run lint:fix— runseslint src --fix
If you plan to publish this package to the npm registry, follow these recommended steps. This package is scoped to @zimbra in package.json, so scoped publishing requires publishing as public (unless your registry config differs).
- Ensure
versioninpackage.jsonis updated (semantic versioning). - Run a local pack check:
npm pack --dry-run- Login to npm (if necessary):
npm login- Publish the package (scoped packages often require
--access public):
npm publish --access public- After publishing, update any downstream repos to use the new version.
- If you use a private registry (Artifactory/Nexus), adapt the publish commands and access settings to your registry's requirements.
- Consider automating the publish workflow via CI with a release job that runs tests, bump version, and publishes on tags.
- When adding or changing rules, update
src/rulesand corresponding configs insrc/configs/. - Run
npm run lintbefore submitting changes. - Provide unit tests for custom rules and document breaking changes clearly.
This repository includes a LICENSE file at the project root. See LICENSE for the full terms.
Open an issue in this repository for questions, or contact the maintainers for onboarding help.