Prettier ESLint Integrator
Prettier-ESLint is a JavaScript utility that orchestrates code formatting by running Prettier first, then applying ESLint's `--fix` functionality. This sequential approach is crucial for maintaining consistent code style across projects, as it resolves potential conflicts between Prettier's opinionated formatting and custom ESLint rules. The current stable version is 16.4.2, with an active development branch targeting version 17 which introduces support for ESLint v9's flat configuration. The package is actively maintained with regular patch and minor releases, alongside a new major version in alpha. It differentiates itself by providing a single programmatic interface to combine these tools, ensuring that ESLint fixes are applied *after* Prettier's formatting, thus preventing ESLint from undoing Prettier's work.
Common errors
-
Error: ESLint: The 'parser' option is deprecated. Please use the 'languageOptions.parser' option instead.
cause Using ESLint v9 with `prettier-eslint` versions prior to v17 that do not fully support ESLint's flat configuration.fixUpgrade `prettier-eslint` to `v17.0.0-alpha.0` or later and migrate your ESLint configuration to the flat config format (`eslint.config.js`). -
Error: Cannot find module 'prettier-eslint'
cause CommonJS `require()` used for an ESM-first package in a Node.js context, or package not installed/path incorrect.fixFor ESM projects, use `import prettierEslint from 'prettier-eslint';`. For CommonJS projects that need dynamic loading, use `const { default: prettierEslint } = await import('prettier-eslint');`. Ensure the package is installed: `npm install prettier-eslint`. -
ESLint: Definition for rule 'indent' was not found.
cause ESLint rules that affect formatting (like `indent`) conflict with Prettier. `prettier-eslint` is designed to run Prettier first, then ESLint fixes. If `eslint-config-prettier` is not used, ESLint might try to fix formatting already handled by Prettier.fixEnsure `eslint-config-prettier` is installed and properly extended in your ESLint configuration to disable conflicting formatting rules. For example, in `.eslintrc.js`: `extends: ['eslint:recommended', 'prettier']`. -
Prettier encountered an error. This is likely a bug in Prettier or one of its plugins.
cause Often caused by an unsupported version of Prettier, a breaking change in Prettier's API not yet supported by `prettier-eslint`, or a malformed input file.fixCheck the `prettier-eslint` changelog for compatibility with your `prettier` version. Ensure `prettier` is updated to a compatible version with `prettier-eslint` (e.g., `prettier@^3.1.0` for `prettier-eslint@^16.1.2`). -
Error: Cannot find module 'tslib'
cause `tslib` is a runtime dependency (since `v16.4.2`) but is missing from `node_modules`.fixInstall `tslib` as a direct dependency: `npm install tslib` or `yarn add tslib`. Verify it's present in your `package.json` and `node_modules`.
Warnings
- breaking Version 17.0.0-alpha.0 introduces support for ESLint v9's flat configuration. Users migrating to ESLint v9 will need to upgrade to `prettier-eslint` v17 or later and adjust their configuration accordingly. Older `.eslintrc.*` files will not be compatible with ESLint v9 and by extension, `prettier-eslint` v17.
- gotcha When using `prettier-eslint` with Svelte files (support introduced in v16.3.0), you must install `svelte-eslint-parser` and `prettier-plugin-svelte` as peer dependencies. Without them, Svelte files will not be processed correctly.
- breaking Prettier v3 introduced breaking changes that required updates in `prettier-eslint`. Versions prior to `16.1.2` might have compatibility issues or unexpected behavior when used with Prettier v3.
- gotcha Beginning with `v16.4.2`, `tslib` was explicitly added as a direct dependency. While usually installed automatically, environments with strict dependency resolution or custom build setups might encounter 'Cannot find module 'tslib'' errors if it's not present.
- gotcha `prettier-eslint` performs formatting by running Prettier *then* ESLint `--fix`. If you desire ESLint fixes to run first, or if you encounter unexpected formatting, be aware of the `prettierLast` option which can reverse this order.
Install
-
npm install prettier-eslint -
yarn add prettier-eslint -
pnpm add prettier-eslint
Imports
- prettierEslint
const prettierEslint = require('prettier-eslint');import prettierEslint from 'prettier-eslint';
- Options
import { Options } from 'prettier-eslint';import type { Options } from 'prettier-eslint'; - prettierEslint
import prettierEslint from 'prettier-eslint'; // in CJS module
const { default: prettierEslint } = await import('prettier-eslint');
Quickstart
import prettierEslint from 'prettier-eslint';
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
import { join } from 'node:path';
// Create a dummy ESLint config for demonstration
const eslintConfigContent = `module.exports = {
env: { node: true, es2021: true },
extends: ['eslint:recommended', 'prettier'],
parserOptions: { ecmaVersion: 'latest' },
rules: {
'semi': ['error', 'never'],
'quotes': ['error', 'single'],
'indent': ['error', 2]
}
};
`;
// Ensure a temporary directory exists for config and file
const tempDir = join(process.cwd(), 'temp-eslint-test');
if (!existsSync(tempDir)) {
mkdirSync(tempDir, { recursive: true });
}
const eslintConfigFile = join(tempDir, '.eslintrc.js');
const tempFilePath = join(tempDir, 'example.js');
writeFileSync(eslintConfigFile, eslintConfigContent);
const rawCode = `const myVar = "Hello world" ; function test ( ) { console . log ( myVar ) ; } test ( ) ;`;
writeFileSync(tempFilePath, rawCode);
async function formatCode() {
try {
console.log('Original code:\n', rawCode);
const formattedCode = await prettierEslint({
text: rawCode,
filePath: tempFilePath, // Essential for ESLint to find its config
eslintConfig: { // Can be provided directly or found via filePath
overrideConfigFile: eslintConfigFile,
},
prettierOptions: { printWidth: 80, tabWidth: 2, semi: false, singleQuote: true },
fallbackPrettierOptions: { printWidth: 80, tabWidth: 2, semi: false, singleQuote: true },
logLevel: 'debug',
});
console.log('\nFormatted code:\n', formattedCode);
writeFileSync(tempFilePath.replace('.js', '.formatted.js'), formattedCode);
} catch (error) {
console.error('Error during formatting:', error);
}
}
formatCode();