Skip to content

ESLint

@usels/eslint-plugin catches common mistakes in observable-first React code. Use it to keep $ naming, JSX reads, and render boundary rules consistent.

Terminal window
npm add -D @usels/eslint-plugin eslint@^9

The plugin targets ESLint v9 flat config.

eslint.config.js
import legendPlugin from "@usels/eslint-plugin";
export default [legendPlugin.configs.recommended];

Use recommended for existing codebases. It enables core correctness rules and keeps the highest-churn conditional rule off.

eslint.config.js
import legendPlugin from "@usels/eslint-plugin";
export default [legendPlugin.configs.strict];

Use strict for new codebases that are fully committed to observable-first rendering patterns.

RuleRecommendedStrictPurpose
use-legend/observable-namingerrorerrorObservable variables should end with $
use-legend/no-observable-in-jsxerrorerrorJSX should read observables with .get() or pass them to supported reactive props
use-legend/hook-return-namingwarnerrorPreserve $ suffix when renaming observable fields
use-legend/prefer-for-componentwarnerrorPrefer For over .map() on observable arrays
use-legend/prefer-show-for-conditionalofferrorPrefer Show for observable conditionals
use-legend/prefer-use-observablewarnerrorPrefer observable state over useState when fine-grained updates matter
use-legend/prefer-use-observewarnerrorPrefer observable effects over useEffect for observable reads
use-legend/no-get-in-non-reactivewarnerrorAvoid one-time .get() snapshots in component or hook bodies
use-legend/no-hooks-in-scopeerrorerrorAvoid React hook calls inside scope bodies
eslint.config.js
import legendPlugin from "@usels/eslint-plugin";
export default [
{
plugins: { "use-legend": legendPlugin },
rules: {
"use-legend/observable-naming": "error",
"use-legend/no-observable-in-jsx": "error",
"use-legend/no-hooks-in-scope": "error",
},
},
];

Pair the ESLint plugin with the Vite or Babel / Next.js transform.