Files
plane/docs/eslint.md
2025-12-09 13:26:22 +05:30

3.8 KiB

ESLint in Plane - How It Works

We've recently upgraded our ESLint setup to use typed linting with a single root-level configuration. This means faster lint runs and simpler config management across the entire monorepo.

Key Changes

  1. Single Root Config - Instead of individual eslint.config.mjs files in every package, we now have one config at the repo root that handles all packages and apps
  2. Typed Linting Enabled - ESLint now uses TypeScript's type information for more powerful checks (catching things like floating promises, unsafe any usage, etc.)
  3. ESLint Flat Config - We're using ESLint v9's new flat config format

How to Run ESLint

From the root of the repo:

# Check for lint errors
pnpm check:lint

# Auto-fix lint errors
pnpm fix:lint

VS Code Integration

ESLint should work automatically in VS Code. The extension will:

  • Show inline errors/warnings as you type
  • Use the root eslint.config.mjs for all files in the monorepo

Tip: Make sure you have the ESLint extension installed.

What Gets Linted

The config applies to all TypeScript and JavaScript files across:

  • apps/web, apps/admin, apps/space, apps/live
  • All packages in packages/

Ignored paths:

  • node_modules/, dist/, build/, .next/, .turbo/
  • Config files (*.config.{js,mjs,cjs,ts})
  • Public folders

Rules Overview

We're enforcing warnings (not errors) for most rules during the transition period. Key categories:

Category What It Catches
TypeScript no-explicit-any, no-floating-promises, no-unsafe-* family, unused vars
React Display names, hooks rules (including new React Compiler rules), refresh exports
Accessibility Alt text, keyboard events, ARIA roles, focus management
Imports Type imports style (prefer-top-level), unresolved imports
Promises Always return, catch-or-return

Adding New Packages

When creating a new package, you don't need to add an ESLint config. Just ensure:

  1. The package has a tsconfig.json
  2. The tsconfig.json is discoverable via the pattern {apps,packages}/*/tsconfig.json

The root config will automatically pick it up.

Suppressing Warnings

If you need to suppress a specific warning:

// Single line
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const data: any = response;

// Block
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
// ... code
/* eslint-enable @typescript-eslint/no-unsafe-assignment */

Please use sparingly - most warnings indicate real issues that should be fixed.

Pre-commit Hook

Lint-staged runs automatically on commit via Husky:

  • Prettier formats your staged files
  • ESLint fixes what it can (with --max-warnings=0)

If the commit fails due to lint errors, fix them before committing.

Reference Files

Help Us Improve!

If you have the time, please consider trying to put up PRs to turn the rules I've set to warn to error, or getting all of strict mode in TypeScript working for a package (e.g., noUncheckedIndexAccess, strictNullChecks). It'll help prevent bugs at Plane, and your co-workers will unknowingly thank you for it.

If you do decide to tackle this, please feel free to reach out to @lifeiscontent for advice on issues you get stuck on.

Thanks!