eslint-plugin-friday
v1.0.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 nextFriday from "eslint-plugin-friday";
export default [
nextFriday.configs["base/recommended"],
nextFriday.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 nextFriday from "eslint-plugin-friday";
export default [
{
plugins: { "next-friday": nextFriday },
rules: {
"next-friday/no-direct-date": "error",
},
},
];Rules
🔧 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 values for environment variables as they can be dangerous in production | | | 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-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 groups | 🔧 | | 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
