npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

eslint-config-reactify

v2.0.1

Published

ESLint 10 flat config for React, Next.js, and Node.js — bundled plugins, zero setup

Readme

eslint-config-reactify

A comprehensive ESLint configuration for React, Node.js, and Next.js TypeScript projects. ESLint 10 flat config only — pick /react, /node, or /next for your stack.


✨ Features

  • ESLint 10 flat config (eslint.config.js)
  • ✅ Pre-configured for React, TypeScript, JSX, imports, tests, and more
  • ✅ Optional JSDoc and TSDoc extras (/extra/jsdoc, /extra/tsdoc)
  • ✅ Opinionated formatting via @stylistic/eslint-plugin
  • ✅ Linting for test files, config files, JSON, and imports
  • ✅ Includes rules from 15+ ESLint plugins

Requirements


📦 Installation

npm install -D eslint@^10 eslint-config-reactify
# or
yarn add -D eslint@^10 eslint-config-reactify
# or
pnpm add -D eslint@^10 eslint-config-reactify

Only eslint is required as a peer dependency. All plugins are bundled.


🚀 Usage

Flat Config

Import the config that matches your stack:

| Entry | Use for | |-------|---------| | eslint-config-reactify/react | React + TypeScript | | eslint-config-reactify/node | Node.js (no React) | | eslint-config-reactify/next | Next.js |

// eslint.config.mjs
import config from 'eslint-config-reactify/react';

export default [
    ...config
    // Other configs
];

Optional extras

Documentation plugins are not included in the main configs. Add them when you want JSDoc/TSDoc linting:

| Entry | Use for | |-------|---------| | eslint-config-reactify/extra/jsdoc | JSDoc comments on JS/TS files | | eslint-config-reactify/extra/tsdoc | TSDoc syntax on TypeScript files |

// eslint.config.mjs
import config from 'eslint-config-reactify/react';
import jsdoc from 'eslint-config-reactify/extra/jsdoc';
import tsdoc from 'eslint-config-reactify/extra/tsdoc';

export default [
    ...config,
    ...jsdoc,
    ...tsdoc,
];

Next.js (eslint-config-next)

ESLint 10 flat config allows each plugin ID (for example import, react, react-hooks, @typescript-eslint) to be registered only once in the merged config. eslint-config-next and eslint-config-reactify both attach those plugins, which triggers Cannot redefine plugin … in the VS Code ESLint extension if you spread both configs verbatim.

Spread Next’s config first, then map every reactify slice through a small helper that drops only the plugin entries Next already owns. Rules, settings, and other plugins (for example @stylistic, perfectionist, json) stay on the slice, so behavior stays the same aside from sharing Next’s plugin instances.

npm install -D eslint@^10 eslint-config-next eslint-config-reactify
# or
yarn add -D eslint@^10 eslint-config-next eslint-config-reactify
# or
pnpm add -D eslint@^10 eslint-config-next eslint-config-reactify

Use the eslint-config-reactify/next entry. It layers the default Next flat setup (core-web-vitals, typescript, globalIgnores) and then reactify with duplicate plugins stripped so ESLint does not throw Cannot redefine plugin ….

Note: Some transitive dependencies of eslint-config-next (for example eslint-plugin-react) may still declare ESLint 9 peer ranges until upstream releases ESLint 10 support. If install fails on peer deps, use your package manager’s legacy-peer-deps option or track vercel/next.js#91702.

// eslint.config.mjs
import config from 'eslint-config-reactify/next';

export default config;

Add your own config objects after importing if you need overrides.

Node.js (TypeScript / JavaScript)

For server-side projects without React, use eslint-config-reactify/node. It shares the same stylistic, import, and TypeScript conventions as the React config but omits React, JSX, TanStack Router/Query, and jest-dom. Add /extra/jsdoc and /extra/tsdoc separately if you want documentation linting.

// eslint.config.mjs
import config from 'eslint-config-reactify/node';

export default [...config];

Migrating to v2 (ESLint 10)

This release requires ESLint 10 and Node.js >=20.19.0. See the official ESLint 10 migration guide.

Breaking changes

  • ESLint 10 only — peer dependency is eslint@^10.0.0
  • No .eslintrc support — ESLint 10 removed the legacy config format; the /legacy entry was removed
  • Explicit subpath imports only — use eslint-config-reactify/react, /node, or /next (no bare package import)
  • JSDoc/TSDoc optional — no longer in main configs; import /extra/jsdoc and /extra/tsdoc if needed
  • Node.js — v20.19+, v22.13+, or v24+ required

What you may notice after upgrading

  • New eslint:recommended rules: no-unassigned-vars, no-useless-assignment, preserve-caught-error
  • JSX identifiers are now tracked as references (fewer false no-unused-vars reports in React code)
  • /* eslint-env */ comments are errors — remove them from your codebase
  • Config lookup starts from each linted file’s directory (ESLint 10 default)
  • Some bundled plugins still declare ESLint 9 peer ranges; this package uses @eslint/compat shims until upstream releases catch up

🔧 Overriding Rules

In eslint.config.js:

import config from 'eslint-config-reactify/react';

export default [
  ...config,
  {
    rules: {
      'no-console': 'warn',
    },
  },
];

📁 Ignored by Default

These folders and files are excluded:

dist, build, coverage, node_modules, public, out, storybook-static, .next, .turbo, .cache, turbo.json

📚 Rules Included

🧠 Core Logic & Styling — @stylistic/eslint-plugin

  • @stylistic/semi: require semicolons
  • @stylistic/quotes: enforce single quotes
  • @stylistic/indent: 4-space indentation
  • @stylistic/comma-dangle: trailing commas for multiline
  • @stylistic/max-len: 256 character line limit
  • @stylistic/no-extra-semi: disallow extra semicolons
  • @stylistic/lines-between-class-members: spacing in classes
  • @stylistic/type-named-tuple-spacing: spacing in tuples
  • and more...

💡 React — eslint-plugin-react, react-hooks, react-refresh

  • react/jsx-key: enforce keys in lists
  • react/button-has-type: require type on <button>
  • react/jsx-sort-props: consistent prop order
  • react/jsx-tag-spacing: spacing in tags
  • react/self-closing-comp: enforce self-closing tags
  • react/function-component-definition: enforce arrow components
  • react-refresh/only-export-components: safe HMR boundaries
  • and more...

⚙️ TypeScript — @typescript-eslint/eslint-plugin

  • @typescript-eslint/consistent-type-imports: Enforces consistent type import style with inline type imports preference
  • @typescript-eslint/no-empty-object-type: off
  • @typescript-eslint/no-explicit-any: off (explicit any allowed)
  • @typescript-eslint/no-non-null-assertion: off (relaxed)
  • @typescript-eslint/no-unnecessary-condition: off
  • @typescript-eslint/prefer-nullish-coalescing: off
  • @typescript-eslint/sort-type-constituents: off (custom sorting used)
  • and more...

📦 Import Handling — eslint-plugin-import, simple-import-sort, import-newlines

  • import/consistent-type-specifier-style: off
  • import/exports-last: off
  • import/extensions: off
  • import/group-exports: off
  • import/namespace: enforce import syntax (with computed allowed)
  • import/newline-after-import: enforce newline after import
  • import/no-default-export: off
  • import/no-duplicates: disallow duplicate imports
  • import/no-extraneous-dependencies: off
  • import/no-named-as-default: off
  • import/no-unresolved: off
  • import-newlines/enforce: enforce newlines in import lists (30 items, max-len 240)
  • simple-import-sort/exports: warn
  • simple-import-sort/imports: warn

📚 Documentation (optional extras)

Import separately — not included in /react, /node, or /next:

  • eslint-config-reactify/extra/jsdocjsdoc/require-description, jsdoc/require-throws, and related JSDoc rules
  • eslint-config-reactify/extra/tsdoctsdoc/syntax for TypeScript files

🔬 Code Quality — sonarjs, perfectionist, no-secrets

  • sonarjs/...: complexity, duplication, etc.
  • no-secrets/no-secrets: detect secrets in code
  • perfectionist/sort-exports: sorted exports with comment partitioning
  • perfectionist/sort-imports: off (we use simple-import-sort)
  • perfectionist/sort-jsx-props: off (covered by react/jsx-sort-props)
  • perfectionist/sort-modules: sorted modules with comment partitioning
  • perfectionist/sort-union-types: sorted union types (custom groups)

🧪 Test Files — eslint-plugin-jest & eslint-plugin-jest-dom

Applied to test/**, **/*.test.{js,jsx,ts,tsx}, and **/*.spec.{js,jsx,ts,tsx} and includes:

  • jest-dom/...: recommended DOM testing rules
  • jest/...: recommended Jest rules

🔧 Misc

  • *.json: enabled with eslint-plugin-json
  • src/pages/**/*.tsx: relaxed React rules for Next.js-style routes (i.e, Tanstack Router)
  • src/types/*.ts & src/stores/*.ts: relaxed export rules
  • .cz-config.cjs, jest.setup.ts, postcss.config.js: relaxed for CommonJS usage

✅ Example Project Setup

npm install -D eslint@^10 eslint-config-reactify
# or
yarn add -D eslint@^10 eslint-config-reactify
# or
pnpm add -D eslint@^10 eslint-config-reactify

Create eslint.config.js:

import config from 'eslint-config-reactify/react';

export default [...config];

Optional: add eslint-config-reactify/extra/jsdoc and /extra/tsdoc for documentation rules (see Optional extras).

Add a lint script:

{
  "scripts": {
    "lint": "eslint . --report-unused-disable-directives --max-warnings 0 --no-warn-ignored --fix"
  }
}

Then run npm run lint, yarn lint, or pnpm run lint.


🤖 Train Cursor & AI Agents (save tokens)

AI agents (Cursor, Copilot, Claude Code, etc.) start every session with no memory of your project. Left alone, they re-explore the repo, re-read eslint.config.mjs, and re-derive your conventions each time — burning tokens and sometimes guessing wrong.

You can "train" them once by committing a small context file that they read automatically. This is the same idea as this package: centralize conventions so nobody (human or agent) rediscovers them.

How it saves tokens

  • No repeated exploration — the agent reads one short file instead of scanning many source files.
  • Fewer wrong guesses — it knows up front: flat config only, no Prettier, arrow components, /next for Next.js, etc.
  • Smaller prompts — a ~1 screen cheat sheet replaces thousands of tokens of file reads per session.

Setup

This package ships copy-paste templates under templates/:

| File | Where it goes | |------|---------------| | templates/AGENTS.md | Your app repo root (AGENTS.md) — read by most agents | | templates/cursor-rule-reactify.mdc | .cursor/rules/ — auto-loaded by Cursor |

  1. Copy templates/AGENTS.md to your repo root and adjust paths/stack.
  2. Copy templates/cursor-rule-reactify.mdc to .cursor/rules/ for Cursor to load it every session.
  3. Commit both so the whole team (and their agents) inherit the same context.

Other tools read the same content under different names — Copilot uses .github/copilot-instructions.md, Claude Code uses CLAUDE.md. Point them at the same conventions.

The key rule to give agents: don't re-read the repo to infer style — AGENTS.md + eslint.config.mjs are authoritative, run lint instead of guessing.


📄 License

MIT © hamidyfine