How to setup Next.js project with TypeScript, ESLint and Prettier
Tags: nextjs, typescript, eslint, prettier
Published: 2022-03-03 23:06:47

## Introduction
Have you ever struggled what packages should be installed to set up a project? Should I install `eslint-config-airbnb` or `eslint-config-airbnb-base`? What is `eslint-plugin-jsx-a11y`? Is it still needed to install `eslint-plugin-react` and `eslint-plugin-react-hooks`?

When I start doing research, I have seen people installed a pile of packages. I always question do I really need them all.

It's good to have a cheat sheet to follow so that every time we can create a clean new project with all toolkits ready. Here is mine for a Next.js project.

The **VS Code Config** part is based on this post [How to get ESlint and Prettier to play nice in VS Code?](https://rohit.page/blog/posts/how-to-get-prettier-eslint-play-nicely-with-vscode/) From which a new setting of `codeActionsOnSave` is introduced.

**Toolkits:**
1. Typescript
2. ESLint
3. Prettier
4. Editor Ruler (80,100,120, color: hotpink)

---

## Pre-requisite

- VS Code
- VS Code plugin: [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint), [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode), [Format Code Action](https://marketplace.visualstudio.com/items?itemName=rohit-gohri.format-code-action)

---

## VS Code Config
1. `Cmd + Shift + P` to open Command Palette
2. Type `setting`
3. Select `Preferences: Open Settings (JSON)`
4. Add below config:
```json
{
  "editor.rulers": [80, 100, 120],
  "workbench.colorCustomizations": {
    "editorRuler.foreground": "#FF69B4"
  },
  "editor.formatOnSave": false,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": {
    "source.formatDocument": true,
    "source.fixAll.eslint": true
  }
}
```

---

## Create new project
[Next.js - TypeScript](https://nextjs.org/docs/basic-features/typescript)
Run below command:
```sh
npx create-next-app@latest --ts <MY_APP_NAME>
```
With the flag `--ts`, Typescript related packages like `@types/node` and `@types/react` would be included. File extension would become `.tsx` instead of `.jsx`. A file `tsconfig.json` which is used by Typescript compiler would be prepared and with a list of default setting like `"target": "es5"` and `"strict": true`. 

---

## Setting up ESLint
Since version 11.0.0, Next.js already integrated  ESLint. We neither have to install ESLint package nor create `.eslintrc.json` file manually.

`eslint-config-next` could be found in `package.json` which below 3 recommended rule-set are used.
- eslint-plugin-react
- eslint-plugin-react-hooks
- eslint-plugin-next

You can check [eslint-config-next](https://github.com/vercel/next.js/blob/canary/packages/eslint-config-next/index.js) for more details (It's even included `@typescript-eslint/parser` and `jsx-a11y`). 

_Note: jsx-a11y is a static AST checker for accessibility rules on JSX elements. [npm web site](https://www.npmjs.com/package/eslint-plugin-jsx-a11y) shows its supported rules._

So, I am happy with the built-in parser and rule-sets but it lacks the airbnb style. According to [Next.js](https://nextjs.org/docs/basic-features/eslint), it is not recommended to install overlapping ESLint plugin

> This eliminates the risk of collisions or errors that can occur due to importing the same plugin or parser across multiple configurations.

So I only install `eslint-config-airbnb-base` additionally then should be good to go.
```sh
npm i -D eslint-config-airbnb-base
```
Add `airbnb-base` to `.eslintrc.json`
```json
{
  "extends": ["next/core-web-vitals", "airbnb-base"]
}
```
_Note: **eslint-config-airbnb** is a collection of a bunch of plugins including `eslint-plugin-import`, `eslint-plugin-react`, `eslint-plugin-react-hooks`, and `eslint-plugin-jsx-a11y` while **eslint-config-airbnb-base** is only the core part of airbnb style._

If you want to customise the rules, set the rule to `warn` or `off` manually in `.eslintrc.json`.
```json
{
  "extends": ["next/core-web-vitals", "airbnb-base"],
  "rules": {
    "no-unused-vars": "warn"
  }
}
```

---

## Setting up Prettier
Now VS Code will alert you with the error underline. We want Prettier to help format our code nicely.
![screen](https://ik.imagekit.io/c5xc1x6srka/screenshot/screen_vscode_GzrOutHhttD.png)
So we create a new file `.prettierrc`. And add below:
```json
{
  "singleQuote": true
}
```

**Should I specify parser in Prettier?**
From [Prettier](https://prettier.io/docs/en/options.html#parser):

> Prettier automatically infers the parser from the input file path, so you shouldn’t have to change this setting.

**Side Dish**
Prettier has not yet format long string. There is a [discussion on break strings](https://github.com/prettier/prettier/issues/4123) in Prettier community 
![screen](https://ik.imagekit.io/c5xc1x6srka/screenshot/screen_vscode_QT2fGZtg8.png)

---

## Conclusion
I hope you have got some basic ideas what packages we already have by default and minimised the amount of packages to be installed for basic setup. Now I have a clean project with all the toolkits I need and without packages that might cause collision. 

After all, you should only install those as `devDependencies` and won't affect the size of production build (For Typescript, I am not sure. Official doc recommends to install globally, but someone in [this discussion](https://github.com/loopbackio/loopback.io/issues/509) said global install would be an anti-pattern. What do you think? Do you install typescript globally or locally, and why? Please let me know).

---

## Things to think about
1. As Prettier formats your code on save, some files like `_app.tsx` won't be formatted unless you open it and save it once. You can run the command `npm run lint` to lint whole project so that no file would be left unformatted. I wonder if there is any tools could help auto formatting after lint.
2. When learning typescript, there comes a term **tsc** means typescript compiler. I am not sure when to use it or do I need to use it manually cos I have built some typescript projects and never use it once. 

Photo by [SHVETS](https://www.pexels.com/@shvets-production?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels) production from [Pexels](https://www.pexels.com/photo/pile-of-cardboard-boxes-scattered-on-floor-during-relocation-7203788/?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels)