eslint-plugin-friday
v2.1.0
Published
Opinionated ESLint rules for consistent, readable TypeScript and React codebases.
Maintainers
Readme
eslint-plugin-friday
Opinionated ESLint rules for consistent, readable TypeScript and React codebases.
eslint-plugin-friday ships 45 rules across two flat-config presets. Each preset comes in a warn variant and a stricter recommended variant set to error. The rules push code toward one explicit, uniform shape — predictable naming, flat structure, and no hidden complexity — so the whole team reads and reviews the codebase the same way.
Features
- 45 focused rules spanning naming, file structure, imports, types, and React and JSX patterns.
- Flat config only, built for ESLint 9+ and
eslint.config.mjs. - Two presets and two severities —
baseandreact, each available aswarnorrecommended. - Fully typed, shipped as dual ESM and CommonJS with type definitions for both.
- Every rule documented with rationale, valid and invalid examples, options, and a when-not-to-use note.
- 100% test coverage, enforced in CI.
Requirements
- ESLint
>=9with flat config - Node.js
>=22.10.0
Installation
pnpm add -D eslint-plugin-fridaynpm install -D eslint-plugin-friday and yarn add -D eslint-plugin-friday work the same way.
Usage
Add a preset to eslint.config.mjs:
import friday from "eslint-plugin-friday";
export default [
friday.configs["base/recommended"],
friday.configs["react/recommended"],
];The react preset adds only the React and JSX rules, so a React project enables both the base and react presets, as shown above.
Choose a preset and severity
| Config | Severity | Scope |
| ------------------- | -------- | ----------------------- |
| base | warn | Any TypeScript project |
| base/recommended | error | Any TypeScript project |
| react | warn | React and JSX projects |
| react/recommended | error | React and JSX projects |
| all | warn | Every rule, both layers |
| all/recommended | error | Every rule, both layers |
The all and all/recommended presets enable every rule the plugin ships, across both the base and React layers.
Enable a single rule
import friday from "eslint-plugin-friday";
export default [
{
plugins: { friday },
rules: {
"friday/no-direct-date": "error",
},
},
];Migrating from the legacy namespace
The ESLint plugin namespace changed from next-friday to friday. Rewrite configuration written against the old namespace:
| Before | After |
| ------------------------------- | ------------------------------ |
| nextFriday | friday |
| plugins["next-friday"] | plugins.friday |
| next-friday/no-direct-date | friday/no-direct-date |
| next-friday/base | friday/base |
| next-friday/base/recommended | friday/base/recommended |
| next-friday/react | friday/react |
| next-friday/react/recommended | friday/react/recommended |
Rule overrides such as "next-friday/no-direct-date": "off" stop matching after this change. The npm package name eslint-plugin-friday and the GitHub organization next-friday keep their names.
Rules
💼 Configurations enabled in.
✅ Set in the base/recommended configuration.
⚛️ Set in the react/recommended configuration.
🔧 Automatically fixable by the --fix CLI option.
| Name | Description | 💼 | 🔧 | | :--------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :- | :- | | boolean-naming | Enforce boolean variables and parameters to have a prefix like is, has, should, can, did, will for better readability | ✅ | | | constant-case | Enforce SCREAMING_SNAKE_CASE for global magic-number, magic-text, bigint, and RegExp constants | ✅ | | | hook-filename | Enforce that files exporting custom hooks are named *.hook.ts or *.hooks.ts | ✅ | | | hook-naming | Enforce 'use' prefix for functions in *.hook.ts and *.hooks.ts files | ✅ | | | index-export-only | Require index files to contain only imports, re-exports, and type declarations | ✅ | | | jsx-newline-between-elements | Require empty lines between sibling JSX elements | ⚛️ | 🔧 | | jsx-no-data-array | Disallow top-level arrays of object literals in .tsx/.jsx files; extract them to a data file | ⚛️ | | | jsx-no-data-object | Disallow top-level nested object literals in .tsx/.jsx files; extract them to a data file | ⚛️ | | | jsx-no-newline-single-line-elements | Disallow empty lines between single-line sibling JSX elements | ⚛️ | 🔧 | | jsx-no-non-component-function | Disallow non-component functions defined at top level in .tsx and .jsx files | ⚛️ | | | jsx-no-sub-interface | Disallow sub-interfaces and helper types in component files; keep only the main component props and extract the rest | ⚛️ | | | jsx-require-suspense | Require lazy-loaded components to be wrapped in Suspense | ⚛️ | | | jsx-simple-properties | Enforce JSX props to only contain strings, simple variables, or ReactNode elements | ⚛️ | | | jsx-sort-properties | Enforce JSX props are sorted by value type: strings, hyphenated strings, numbers/booleans, expressions, objects/arrays, functions, JSX elements, then shorthand booleans | ⚛️ | 🔧 | | jsx-spread-properties-last | Enforce JSX spread attributes appear after all other props | ⚛️ | | | no-complex-inline-return | Disallow complex inline expressions in return statements - prefer extracting to a const first | ✅ | | | no-direct-date | Disallow direct usage of Date constructor and methods to enforce centralized date utilities | ✅ | | | no-emoji | Disallow emoji characters in source code | ✅ | | | no-environment-fallback | Disallow fallback/default values for environment variables because they can hide missing configuration | ✅ | | | no-ghost-wrapper | Disallow bare and elements that have no meaningful attributes, known as Divitis or ghost wrappers | ⚛️ | | | no-inline-nested-object | Require object or array values passed to functions, returned, or used as JSX attributes to span multiple lines when they contain nested objects or arrays | ✅ | 🔧 | | no-inline-return-properties | Require return object properties to use shorthand notation by extracting non-shorthand values to const variables | ✅ | | | no-lazy-identifiers | Disallow lazy, meaningless variable names that hurt code readability | ✅ | | | no-logic-in-parameters | Disallow logic or conditions in function parameters - extract to a const variable first | ✅ | | | no-magic-numbers | Disallow magic numbers outside well-known values because unnamed constants hide intent | ✅ | | | no-misleading-constant-case | Disallow SCREAMING_SNAKE_CASE for non-constant or non-static values | ✅ | | | no-misleading-service-prefix | Disallow misleading function name prefixes in *.service.ts files | ✅ | | | no-nested-interface-declaration | Disallow inline object type literals in interface or type properties | ✅ | | | prefer-destructuring-parameters | Enforce destructuring for functions with multiple parameters | ✅ | | | prefer-guard-clause | Enforce guard clause pattern instead of nested if statements | ✅ | | | prefer-inline-literal-union | Enforce inlining literal union types in interface properties instead of using type aliases for better IDE hover information | ✅ | 🔧 | | prefer-interface-for-component-properties | Enforce 'interface' over 'type' alias for component prop declarations in *.tsx and *.jsx files | ⚛️ | 🔧 | | prefer-interface-over-inline-types | Enforce interface declarations over inline type annotations for React component props | ✅ | | | prefer-named-parameter-types | Enforce named interfaces/types instead of inline object types for function parameters | ✅ | | | prefer-properties-with-children | Prefer PropsWithChildren over manually declaring children: ReactNode in component props | ⚛️ | | | prefer-react-import-types | Enforce importing React types and utilities from 'react' instead of using React.X | ⚛️ | | | prefer-readonly-component-properties | Enforce Readonly wrapper for React component props when using named types or interfaces | ⚛️ | 🔧 | | properties-suffix | Enforce 'Props' suffix for interfaces and types in *.tsx files | ✅ | | | render-naming | Enforce 'render' prefix for variables that hold or return JSX inside React components | ✅ | | | sort-destructuring | Enforce alphabetical sorting of destructured properties with defaults first | ✅ | 🔧 | | sort-exports | Enforce a consistent ordering of export groups | ✅ | 🔧 | | sort-imports | Enforce a consistent ordering of import declarations | ✅ | 🔧 | | sort-type-alphabetically | Enforce alphabetical sorting of properties within required and optional groups in TypeScript interfaces and type aliases | ✅ | 🔧 | | sort-type-required-first | Enforce required properties come before optional properties in TypeScript interfaces and type aliases | ✅ | 🔧 | | test-filename | Enforce that files containing test code are named *.test.ts or *.test.tsx | ✅ | | | type-declaration-order | Enforce that referenced types and interfaces are declared after the type that uses them | ✅ | |
Security
To report a vulnerability privately, see the security policy.
Contributing
See CONTRIBUTING for the development workflow, commit convention, and quality gates.
License
MIT © Next Friday
