eslint-plugin-functional
raw JSON → 9.0.4 verified Sat Apr 25 auth: no javascript
ESLint plugin enforcing functional programming patterns in JavaScript and TypeScript, v9.0.4 (Feb 2026). Requires ESLint ^9.0.0 or ^10.0.0 and TypeScript >=4.7.4. Actively maintained with monthly releases. Provides presets (strict, recommended, lite) and categorized rulesets for immutability, no statements, no exceptions, currying, and stylistic rules. Differentiated by TypeScript-first design, type-aware rules (e.g., type-declaration-immutability), and support for Map/Set mutation detection. Recommended alternative to plugins like eslint-plugin-immutable or writing custom rules.
Common errors
error Error: ESLint configuration in .eslintrc.json is invalid: - The 'extends' property is not supported in flat config. ↓
cause Using legacy .eslintrc.* format with new flat config system introduced in v9.
fix
Migrate to eslint.config.js and use import plugin from 'eslint-plugin-functional' with the plugins and rules object.
error TypeError: Cannot read properties of undefined (reading 'Functional') ↓
cause Misconfigured plugin loading: plugin not listed under 'plugins' in flat config.
fix
Add 'plugins: { functional: plugin }' in the flat config object.
error Parsing error: The 'parserOptions.project' has been set for 'nonexistent.ts' but the project does not exist. ↓
cause Missing or incorrect path to tsconfig.json in parserOptions.project.
fix
Ensure parserOptions.project points to a valid tsconfig.json file that includes the file being linted.
Warnings
breaking v9.0.0: immutable-data rule now detects Map and Set mutations (e.g., .set(), .delete()). Code that mutates Maps/Sets will be flagged unless ignoreMapsAndSets option is set. ↓
fix Set 'ignoreMapsAndSets: true' in the immutable-data rule config if you intentionally mutate Maps/Sets.
breaking v8.0.0: PrivateIdentifier names are now prefixed with '#'. Rules that reference private fields may report differently. ↓
fix Update any custom rule logic or inline configs that check private identifiers to include the '#' prefix.
gotcha no-throw-statements rule requires type checking (marked as requiring type checking since v9.0.2). Ensure parserOptions.project is set and the rule runs only on files included in the TypeScript project. ↓
fix Add 'parserOptions: { project: "./tsconfig.json" }' to the languageOptions for files using this rule.
deprecated Rulesets like 'configs.recommended' are now accessed via named export 'configs'. Old string-based 'extends' patterns (e.g., 'plugin:functional/recommended') may still work but are not the future. ↓
fix Use the flat config format with import: import { configs } from 'eslint-plugin-functional'; then spread configs.recommended.
Install
npm install eslint-plugin-functional yarn add eslint-plugin-functional pnpm add eslint-plugin-functional Imports
- default wrong
const plugin = require('eslint-plugin-functional')correctimport plugin from 'eslint-plugin-functional' - rules wrong
const { rules } = require('eslint-plugin-functional')correctimport { rules } from 'eslint-plugin-functional' - configs wrong
import { recommended } from 'eslint-plugin-functional'correctimport { configs } from 'eslint-plugin-functional'
Quickstart
import plugin from 'eslint-plugin-functional';
import tsParser from '@typescript-eslint/parser';
export default [
{
files: ['src/**/*.ts'],
languageOptions: {
parser: tsParser,
parserOptions: { project: './tsconfig.json' },
},
plugins: { functional: plugin },
rules: {
'functional/immutable-data': 'error',
'functional/no-let': 'error',
'functional/prefer-tacit': 'warn',
},
},
];