Skip to content

Repository files navigation

@zimbra/eslint-config

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.

Table of contents

Overview

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/, including custom-rules used internally.

Quick start

  1. Install the package as a dev dependency in your project.
  2. Install eslint (peer dependency).
  3. Extend @zimbra/eslint-config in your ESLint configuration.

Installation

Install the config and core peer dependency:

npm install --save-dev @zimbra/eslint-config eslint

If you're using TypeScript:

npm install --save-dev @zimbra/eslint-config eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin

Note about consumer installation

This 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-react
  • eslint-plugin-react-hooks
  • eslint-plugin-import
  • eslint-config-prettier and eslint-plugin-prettier
  • eslint-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).

Prettier integration (important)

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 prettier

If 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.

When should I integrate this?

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.

What problem will it resolve?

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.

Usage examples

ESLint Flat Config example (eslint.config.mjs)

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" in package.json or use the .mjs extension 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.

Exports & configs

Main exports from src/index.js

  • coreJsConfig — Base JavaScript config with ESLint recommended rules, import rules, security, and style rules.
  • customConfig — Custom Zimbra rules (includes no-direct-memoize and other custom patterns).
  • reactConfig — React and React Hooks rules (includes plugin setup and recommended rules).
  • preactI18nConfig — Preact i18n rules and configuration (requires ESLINT_INTL_PATH environment variable or defaults to src/intl).
  • prettierConfig — Prettier integration (formatting rules and conflict resolution).
  • automationConfig — Automation/TestCafe rules for test files.
  • localeJsonConfig — i18n JSON validation rules.

Additional exports

  • ./typescript -> src/typescript.js (TypeScript-focused config — exports tsEslintConfig)

Architecture & rule organization

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

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.

Scripts

This repository provides convenience scripts in package.json that are useful for developing the config itself:

  • npm run lint — runs eslint src
  • npm run lint:fix — runs eslint src --fix

Publishing

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).

  1. Ensure version in package.json is updated (semantic versioning).
  2. Run a local pack check:
npm pack --dry-run
  1. Login to npm (if necessary):
npm login
  1. Publish the package (scoped packages often require --access public):
npm publish --access public
  1. After publishing, update any downstream repos to use the new version.

Notes

  • 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.

Contributing

  • When adding or changing rules, update src/rules and corresponding configs in src/configs/.
  • Run npm run lint before submitting changes.
  • Provide unit tests for custom rules and document breaking changes clearly.

License

This repository includes a LICENSE file at the project root. See LICENSE for the full terms.

Support

Open an issue in this repository for questions, or contact the maintainers for onboarding help.

About

ESLint configuration for Modern UI and Modern Zimlets

Resources

Stars

0 stars

Watchers

3 watching

Forks

Releases

Packages

Contributors

Languages