Improving Code Quality With Prettier And ESLint (2023)

No software team should spend time and mental resources arguing about code formatting. The same goes for code practices that some of the team members might consider unsafe or counter-productive. To ensure that, configure your project to use the power duo of Prettier and ESLint — for code formatting and code linting.

A Real-Life Scenario

Imagine reviewing a PR, and immediately noticing a formatting issue: a dangling comma is missing. If you don’t care about being called a nitpicker, you highlight this as a change request.

Down a few more lines of code, the same issue repeated. Scrolling through the PR, you see several more instances of it. Do you add a comment for each? Do you simply put “and so on?” Without even getting to review the business logic, you have already spent 5 minutes and stumbled upon several decisions to be made that could have easily been avoided.

Having formatting errors automatically corrected helps never to run into this kind of situation.

Linter does something similar, but for lousy code practices. Instead of automatically correcting an issue, most of the time, it only highlights that a particular piece of code goes violates the rules agreed upon by the project team. This helps the author to catch and fix the issue before the code review starts.

Improving Code Quality With Prettier And ESLint (1)

What Is Code Formatting and Why Does It Matter?

Code formatting is rather about aesthetics than logic. Things like using single quotes instead of double (if the language allows that) has only residual, if any, effect on performance, complexity or readability.

Having a uniform code formatting however has a huge impact on readability.

When I suddenly see a double-quoted string instead of a single-quoted one, a bunch of questions automatically pop into my head: why is it double-quoted while the rest of the codebase is single? Is it on purpose? If not, is it a mistake? Should I fix this? Should I highlight this? Who added this piece of code (if the quotes are in a refactored code)? When did they do this? Maybe it’s a legacy code?

This slows me down every time I scan through the code. And some people simply take “bad” (= not the one they prefer or the one that was agreed upon) formatting as a personal insult, which makes a dent in their motivation to work on the project.

What Is Linting and Why Does It Matter?

Simply put, linting means avoiding code that might be unsafe, has poor readability, or is potentially hard to maintain.

Do not re-assign function parameters. Do not make var what is supposed to be const. Make sure an async function call is always prepended with an await. Always use a dangling comma.

(Video) ESLint + Prettier + VS Code — The Perfect Setup

99% of the time, ignoring those guidelines introduces room for logical errors and bugs — especially when the code gets refactored.

Why Formatting and Linting Must Be Done Automatically?

If something must be done 100% of the time, the best way to ensure that is to automate it. Otherwise whoever is responsible, will sooner or later slip and forget.

If there are several people working on the code, the chance one of them forgets to apply formatting and linting rules before every push multiplies.

Modern setups allow different approaches to automating formatting and blocking non-linted code from reaching the repository.

Configuring Linting and Code Formatting for TypeScript

The following tools are specific for Node.js / TypeScript development done using the VSCode editor. However, there are similar tools available for most modern programming languages and other editors.

ESLint

ESLint is the de-facto standard tool for linting and sometimes formatting. Its primary goal is to find and print linting and formatting errors. Integrated with an editor such as VSCode via a plugin, it can highlight errors directly in the IDE. Some rules can be applied automatically. In other words, ESLint can change the code to conform with the rules. Others require refactoring from the developer.

ESLint Rules and Configs

There are more than a hundred rules that ESLint supports. Each can be enabled or disabled via ESLint config. Often there’s a more complex configuration available through specific rule options, e.g., treat something as an error with certain exceptions.

There are several popular combinations of ESLint rules distributed as NPM packages: AirBnB, Recommended, Standard.

Improving Code Quality With Prettier And ESLint (2)

You probably want to pick the ruleset that has the most rules you agree with. All rules from those sets can be overridden in the project ESLint config.

The Golden Rule

While ESLint can highlight and correct both formatting and non-formatting (like “don’t re-assign function parameters”) rules, I want those types of rules to be treated differently.

Formatting rules must be always applied automatically with no exceptions.

(Video) VSCode ESLint, Prettier & Airbnb Style Guide Setup

On the other hand, non-formatting rules must never be applied automatically, and I want to be able to commit them locally (but not push to the remote).

Prettier

To split the handling of these two types of rules, and to speed up applying formatting rules, another tool can be used - Prettier. It’s a command line tool with the sole purpose of formatting files according to its own opinionated rule set.

There is some room for configuration (yes, you’ll be able to pick a single or a double quotes) and a VSCode plugin.

If you use Prettier, you will have to install an extra package for ESLint that disables rules that are conflicting with what Prettier does. And make sure to not enable those rules in the ESLint config (otherwise after Prettier applies formatting will always make ESLint yield errors).

Automating In Editor

Since applying formatting will be automated, it should be done as early as possible after the code is added. VSCode allows the code formatting to be applied each time a file is saved. See the “Step-by-Step” section below for VSCode-specific configuration.

Automating with a git Commit/Push Hook

Since a rogue developer might not enable the format-on-save option in their code editor (or their editor might not support it), it makes sense to add a Prettier hook that will automatically apply formatting on each commit.

To make sure that no code with unfixed linter errors gets into the repository, add a lint hook on push to the remote.

Step-by-Step TypeScript Project Configuration

For the tutorial below, I will create a dummy TypeScript API using Apollo GraphQL server.

Initial Project Configuration

  1. Initiate the project
mkdir prettylint && cd prettylint && npm init -y
  1. Install your “business” packages
npm i @apollo/server graphql typescript
  1. Add the package.json prop to enable import (we’re going to use ESModules in this example)
"type": "module",
  1. Create src/index.ts file with some formatting/lint errors:
import { ApolloServer } from '@apollo/server';import { startStandaloneServer } from '@apollo/server/standalone';import { formatComplex, formatNameShort } from './utils/format.js';const books = [ { title: 'The Awakening', author: 'Kate Chopin', }, { title: 'City of Glass', author: 'Paul Auster', },];const persons = [ { firstName: 'John', lastName: 'Appleseed', }, { firstName: 'Robert', lastName: 'Paulson', },];const typeDefs = `#graphql type Book { title: String author: String } type Person { firstName: String lastName: String shortName: String } type Query { books: [Book!]! persons: [Person!]! }`;const resolvers = { Query: { books: () => { console.log('this will return books'); return books }, persons: () => { return persons.map((person) => ({ ...person, shortName: formatNameShort(person.firstName, person.lastName), complexName: formatComplex(person.firstName, person['lastName'], function () { console.log('donk'); }), })); }, },};const server = new ApolloServer({ typeDefs, resolvers,});const { url } = await startStandaloneServer(server, { listen: { port: 4000 },});console.log(`🚀 Server ready at: ${url}`);
(Video) The Power of Custom ESLint: Boost Your Code Quality | Custom Eslint rule | Web dev | Javascript
  1. Add another src/utils/format.ts file:
export const formatNameShort = (first, last) =>`${first.substring( 0,1) }. ${last}`;export const formatComplex = (first: string,last: string,onComplete: () => void,): string => {last = String(5); first = first + "changed";var k = 0;var m = ["a", "b"];var n = ["a", "b"];first = String(k > 0 ? "ye" : k--);return first;};
  1. Create and add the following to tsconfig.json:
{ "compilerOptions": { "rootDirs": ["src"], "outDir": "dist", "lib": ["es2020"], "target": "es2020", "module": "esnext", "moduleResolution": "node", "esModuleInterop": true, "types": ["node"], "paths": { "*": ["./src/*"] }, "baseUrl": ".", "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true }, "include": ["src"], "exclude": ["node_modules", "dist"]}
  1. Update the scripts section in the package.json:
 "scripts": { "compile": "tsc", "start": "npm run compile && node ./dist/index.js" },
  1. Run it:
npm start
  1. Open http://localhost:4000 and try the “books” query.

Improving Code Quality With Prettier And ESLint (3)

Add Prettier

  1. If you haven’t done it already, install the Prettier plugin for your VSCode (or other editor).

Improving Code Quality With Prettier And ESLint (4)

  1. Add a .prettierrc file
{ "singleQuote": true, "trailingComma": "all", "printWidth": 100, "jsxSingleQuote": true}
  1. Cmd+Shift+P → “Workspace Settings” → Enter; “Format on Save”; Check the Editor: Format on Save checkbox.
  2. Next, search for the “Formatter” option in the Workspace Settings, and set it to “Prettier”

Improving Code Quality With Prettier And ESLint (5)

  1. Get back to index.ts and hit Cmd+S. The file will be auto-formatted. If that doesn’t happen, make sure that:
    1. Both “Format on Save” and “Editor: Default Formatter” options are set on the Workspace level, and not set on any other level.
    2. Prettier plugin is installed and enabled (sometimes the editor must be restarted)
    3. There isn’t an .editorconfig file with potentially conflicting configuration
  2. Do the same for utils/format.ts

Add ESLint

  1. Install the necessary packages
npm i --save-dev @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint eslint-config-prettier eslint-plugin-prettier eslint-plugin-import
  1. Add the ESLint config file .eslintrc.cjs
module.exports = { env: { node: true, }, extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], plugins: ['import', 'prettier'], root: true, rules: { 'import/no-extraneous-dependencies': 'off', 'no-console': ['error', { allow: ['warn', 'error'] }], 'no-param-reassign': ['error', { props: false }], 'no-unused-vars': 'off', '@typescript-eslint/no-unused-vars': 'error', '@typescript-eslint/explicit-function-return-type': [ 'error', { allowExpressions: true, allowHigherOrderFunctions: true, allowTypedFunctionExpressions: true, }, ], }, ignorePatterns: ['.eslintrc.cjs', 'dist/*'], // this is necessary for thing to work};
  1. Test manually running the ESLint
npx eslint .

You should see the output full of issues similar to

(Video) 5 Reasons to IMMEDIATELY Turn On ESLint in VS Code

/Users/sp/projects/prettylint/src/index.ts 50:7 error Unexpected console statement no-console 58:11 error Unexpected console statement no-console 74:1 error Unexpected console statement no-console/Users/sp/projects/prettylint/src/utils/format.ts 1:32 error Missing return type on function @typescript-eslint/explicit-function-return-type 3:60 error 'onComplete' is defined but never used @typescript-eslint/no-unused-vars 4:3 error Assignment to function parameter 'last' no-param-reassign 4:3 error 'last' is assigned a value but never used @typescript-eslint/no-unused-vars 5:3 error Assignment to function parameter 'first' no-param-reassign 6:3 error Unexpected var, use let or const instead no-var 7:3 error Unexpected var, use let or const instead no-var 7:7 error 'm' is assigned a value but never used @typescript-eslint/no-unused-vars 8:3 error Unexpected var, use let or const instead no-var 8:7 error 'n' is assigned a value but never used @typescript-eslint/no-unused-vars 9:3 error Assignment to function parameter 'first' no-param-reassign 14 problems (14 errors, 0 warnings) 3 errors and 0 warnings potentially fixable with the `--fix` option.
  1. Now it’s time to have those highlighted by the editor. Install and enable the ESLint extension.

Improving Code Quality With Prettier And ESLint (6)

  1. Restart the IDE and observe

Improving Code Quality With Prettier And ESLint (7)

Add Pre-Commit and Pre-Push Hooks

To recap, I want to be able to commit only formatted code allowing linting errors. I don’t however want any code with linting errors in the repository.

Thus, I configure automatic code formatting in the pre-commit hook, and the linting of only staged files with the pre-push hook. That can be easily done with husky, and lint-staged packages.

Bonus: Rome — An Alternative to the ESLint + Prettier Duo

The Rome package is designed to replace the combination of Prettier and ESLint. Just like Prettier, it is an opinionated formatter with some available configuration, and has its own set of linting rules, unrelated to ESLint.

There’s also a VSCode extension.

Refer to Rome’s Getting Started guide, but note that you might get into conflicts between Prettier, ESLint and Rome if you want to keep all three VSCode extensions enabled.

Reviewed by Kaspars Žarinovs

  • eslint
  • prettier
  • linting
  • nodejs
  • TypeScript
  • formatting
  • collaboration
  • VSCode

Related articles:

  • Secure Cloud Workspace with VSCode and Tailscale
  • Master the Art of Software Testing with F.I.R.S.T Principles
  • Clean Architecture with FastAPI
  • Using Private Modules in Go from GitHub
  • Getting started with Async in Python
(Video) ESLint (and Prettier) Quickstart - Lint your javascipt code the right way

Videos

1. Why I always use ESLint in my projects
(Web Dev Cody)
2. Improve Your Code With ESLint + VsCode + Airbnb Styleguide
(Colt Steele)
3. Code Formatting with Prettier in Visual Studio Code
(James Q Quick)
4. How to configure Prettier & Eslint in React App for formatting & code quality | Part 1 | Hindi
(Yar Coder)
5. Configuring ESLint and Prettier for TypeScript
(LogRocket)
6. Improve Code Quality with Salesforce CLI Scanner | Developer Quick Takes
(Salesforce Developers)
Top Articles
Latest Posts
Article information

Author: Nathanael Baumbach

Last Updated: 01/31/2023

Views: 6175

Rating: 4.4 / 5 (55 voted)

Reviews: 86% of readers found this page helpful

Author information

Name: Nathanael Baumbach

Birthday: 1998-12-02

Address: Apt. 829 751 Glover View, West Orlando, IN 22436

Phone: +901025288581

Job: Internal IT Coordinator

Hobby: Gunsmithing, Motor sports, Flying, Skiing, Hooping, Lego building, Ice skating

Introduction: My name is Nathanael Baumbach, I am a fantastic, nice, victorious, brave, healthy, cute, glorious person who loves writing and wants to share my knowledge and understanding with you.