How to setup NextJS with TypeScript and ESLint + prettier
Tags: typescript, nextjs, eslint, prettier
Published: 2020-05-25 17:46:51

Sharing code on front-end and back-end has always been my dream. NextJS makes it easy with a simple framework including both, simple to run, simple to use.

NextJS makes it really easy to modify its setup, making compatibility a first class citizen.

To jumpstart a NextJS project you don't need anything more than this command.

```sh
$ npm init next-app nextjs-example
```

Change `nextjs-example` to whatever name you want the project to have.

`$ cd nextjs-example` to get in the folder, and now we're ready to start.

## NextJS and TypeScript

NextJS comes with TypeScript just one click away, creates an empty `tsconfig.json` file and run `$ npm run dev`.\
The tsconfig will be populated automatically and all `.js` files are ready to be converted to `.ts`.

Differently from the babel TypeScript presets (used by Gatsby, for example), NextJS will not compile on type errors. I don't feel a great difference between the two options. At the end of the day, if you are using TypeScript you want your types to be correct, regardless of compilation.

## NextJS + prettier

Adding prettier is easily achieved as well.

```sh
$ npm i - prettier
```

And next, create a `.prettierrc` file.

```json
// .prettierrc
{
  "endOfLine": "lf",
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "es5"
}
```

And that's pretty much it.

## NextJS + ESLint

ESLint needs to be configured with both TypeScript and prettier, but also NextJS's React implementation.

There are quite a few libraries that need to be added for this all to work properly.

```sh
npm i -D eslint eslint-loader eslint-plugin-react eslint-config-prettier eslint-plugin-prettier @typescript-eslint/eslint-plugin @typescript-eslint/parser
```

A basic `.eslintrc.js` config will look like this.

```js
// .eslintrc.js
module.exports = {
  // Specifies the ESLint parser
  parser: "@typescript-eslint/parser",
  extends: [
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier/@typescript-eslint",
    "plugin:prettier/recommended",
  ],
  settings: {
    react: {
      version: "detect",
    },
  },
  env: {
    browser: true,
    node: true,
    es6: true,
  },
  plugins: ["@typescript-eslint", "react", "prettier"],
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    // Allows for the parsing of modern ECMAScript features
    ecmaVersion: 2018,
    // Allows for the use of imports
    sourceType: "module",
  },
  rules: {
    // Disable prop-types as we use TypeScript for type checking
    "react/prop-types": "off",
    "@typescript-eslint/explicit-function-return-type": "off",
    "prettier/prettier": "error",
    "@typescript-eslint/interface-name-prefix": "off",
    "@typescript-eslint/no-explicit-any": "off",
    "@typescript-eslint/ban-ts-ignore": "off",
    // needed for NextJS's jsx without react import
    "react/react-in-jsx-scope": "off",
  },
  globals: { React: "writable" },
};
```

I'm not a fan of an over personalized linting config. It takes time away from development and introduces complexity to an accepted standard.

## BONUS: NextJS and Jest

Testing makes apps more reliable and bug fixing easier. I prefer to have it and write tests as the app progresses.

Interviews go a lot better when you display testing skills. Being on the other side of the interview, I always appreciate candidates who can write tests.

Jest is the go-to testing library for React applications, adding it to a NextJS application is not too difficult but requires some changes.

First, the packages. `jest`, `@testing-library/jest-dom` and `@testing-library/react` for testing, and `babel-jest` for the config.

```sh
npm i -D jest @testing-library/jest-dom @testing-library/react babel-jest
```

We need to create a `.babelrc` file to enable the testing environment.

```json
// .babelrc
{
  "presets": ["next/babel"]
}
```

The Jest config is pretty short as well, I removed the `.css` transformations since NextJS includes a good css-in-js solution to handle styles.

```js
// jest.config.js
module.exports = {
  collectCoverageFrom: ["**/*.{ts,tsx}", "!**/*.d.ts", "!**/node_modules/**"],
  // we need to create this file
  setupFilesAfterEnv: ["<rootDir>/setupTests.js"],
  testPathIgnorePatterns: ["/node_modules/", "/.next/",],
  transform: {
    "^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
  },
  transformIgnorePatterns: ["/node_modules/"],
};
```

Last, the setup file for Jest is just one line.

```js
// setupTests.js 
import "@testing-library/jest-dom/extend-expect";
```

## BONUS 2: What about end-to-end tests?

It takes even less time to set up end-to-end testing, [I wrote a small how-to here](https://dev.to/kornil/write-your-first-end-to-end-test-in-5-minutes-4ed6).

---

If you have any questions, feel free to leave a comment.