← Back to Guides

Use Prettier and ESLint in harmony

ESLint is for catching bugs.

Prettier is for formatting code.

Manually formatting your code tricks you into thinking you're improving the codebase while providing zero business value.

When properly configured, ESLint will audit your code for potential bugs. Anything that doesn't match the way Prettier wants to format your code is also flagged as an error, and then triggers Prettier as part of the autofix step.


You'll need to install these four modules.

npm i --save-dev /
eslint /
prettier /
eslint-config-prettier /
eslint-plugin-prettier /
typescript /

Add these scripts to package.json

The lint:changed script will only lint the currently modified files, which is a great way to slowly integrate linting into a messy codebase

"lint": "eslint",
"lint:changed": "eslint $(git diff --name-only --diff-filter=d HEAD ':(exclude)package*.json' | xargs)",
"lint:fix": "eslint --fix"
## Node
Create a `tsconfig.json` and place it in the root of your application
"compilerOptions": {
"target": "es2016",
"lib": ["ESNext"],
"allowJs": true,
"checkJs": true,
"skipLibCheck": true,
"strictNullChecks": false,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"noImplicitAny": false,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"isolatedModules": true,
"jsx": "preserve",
"baseUrl": "./",
"paths": {
"@/*": ["./*"],
"~/*": ["./*"]
// When adding new paths, run this command to make sure it matches the right files
// npx glob-test "pages/**/**/*.{js,ts,jsx,tsx}"
"include": ["**.d.ts", ".eslintrc.js", "./**/**/*.js"],
"exclude": ["node_modules"]

Create a .eslintrc.js file and place it at the root of your application

module.exports = {
env: {
node: true,
jest: true,
extends: [
/** Automatically replaces "" with `` when ${var} is detected inside */
parser: "@typescript-eslint/parser",
parserOptions: {
project: "./tsconfig.json",
plugins: ["@typescript-eslint", "jest", "prettier"],
ignorePatterns: ["package-lock.json"],
rules: {
// Floating promises are usually a sign of forgetting to await
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-var-requires": "off",
// MongoDB uses _id for its document ID
"no-underscore-dangle": ["error", { allow: ["_id"] }],

Want news and updates?

Join a handful of people who get my latest content and product updates, directly to your inbox.