Skip to content

Changelog - 2026-10-06 ​

A React frontend shares one lint source with its backend ​

Feature Behavior Change

In one line. @venizia/dev-configs exports ReactEslintConfigs: the base preset plus what a React frontend needs.

js
// eslint.config.mjs
import { ReactEslintConfigs } from '@venizia/dev-configs';
import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import jsxA11y from 'eslint-plugin-jsx-a11y';

export default ReactEslintConfigs.create({ plugins: { react, reactHooks, jsxA11y } });

What changed ​

Until now, dev-configs had no React rule. A frontend kept a second base preset or re-declared the same rules in every package, and the copies drifted.

ReactEslintConfigs.create() takes the plugins as options, so a backend that never calls it installs nothing new. reactVersion defaults to 'detect'; under ESLint 10, pass it ('19.2'), since eslint-plugin-react 7 cannot detect it there. On top of eslintConfigs it adds:

AddsSetting
React correctness - jsx-key, no-children-prop, no-deprecated and 11 moreerror, .jsx/.tsx
jsx-a11y basics - alt-text, aria-props, aria-role and 6 moreerror, .jsx/.tsx
react-hooks/rules-of-hookserror, .js/.jsx/.ts/.tsx - custom hooks live in .ts too
react-hooks/exhaustive-depswarn, .js/.jsx/.ts/.tsx
@typescript-eslint/consistent-type-importserror, prefer: 'type-imports'
@typescript-eslint/no-explicit-anywarn - the base has it off

It relaxes what a UI does on purpose:

RuleSettingWhy
naming-conventionthe base rule plus PascalCase functions, .jsx/.tsxfunction App() is a component
no-floating-promises, no-voidoffEvent handlers and effects fire promises they do not await
no-invalid-this, no-use-before-defineoffFunction components; a component may be used above its declaration
no-shadowwarn
no-unused-varswarn, _-prefixed names ignored

Rules the automatic JSX runtime or tsc already enforce - react-in-jsx-scope, prop-types, jsx-no-undef, jsx-no-duplicate-props, no-unknown-property - are left out.

The base, for every consumer.

RuleBeforeNow
@typescript-eslint/ban-ts-commentofferror. @ts-expect-error with a description is still allowed
@typescript-eslint/no-namespaceofferror
curlydeclared twicedeclared once, by the upstream preset; same value

Who is affected ​

  • A React frontend. Replace a second base preset, or per-package React rules, with ReactEslintConfigs.create(). Keep only your house rules on top.
  • Code with @ts-ignore, @ts-nocheck, or a bare @ts-expect-error. It now fails lint. Use @ts-expect-error with a reason.
  • Code with a namespace. It now fails lint. Use modules.

Files: packages/dev-configs/src/linters/react-eslint.ts, packages/dev-configs/src/linters/eslint.ts