Skip to content

[Startup MVP recipes #7] Frontend: Next.js linting setup code pointers

It’s time to setup the frontend and we would like to choose Next.js as the base framework. Next.js is based on React and provides server side rendering out of the box, check it out at

Init Next.js project

yarn create next-app --typescript


Please also check official doc where our code is based on and will interact with:

Install dev dependencies (plugins for eslint, prettier etc.)

yarn add -D typescript \
eslint \
prettier \
@typescript-eslint/parser \
@typescript-eslint/eslint-plugin \
eslint-config-airbnb-base \
eslint-config-airbnb-typescript \
eslint-config-prettier \
eslint-plugin-import \
eslint-plugin-prettier \
eslint-plugin-unused-imports \
eslint-plugin-unused-imports \
prettier-plugin-organize-imports \
@next/eslint-plugin-next \
eslint-config-next \
eslint-config-prettier \
husky \

Config files

// .eslintignore

// .eslintrc.js

module.exports = {
  parser: '@typescript-eslint/parser',
  parserOptions: {
    project: 'tsconfig.json',
    tsconfigRootDir: __dirname,
    ecmaVersion: 'latest',
    sourceType: 'module',
  plugins: ['@typescript-eslint', 'prettier', 'import', 'unused-imports'],
  extends: [
  rules: {
    '@typescript-eslint/interface-name-prefix': 'off',
    '@typescript-eslint/explicit-function-return-type': 'off',
    '@typescript-eslint/explicit-module-boundary-types': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    'no-unused-vars': 0,
    '@typescript-eslint/no-unused-vars': 0,
    'unused-imports/no-unused-imports': 1,
    'unused-imports/no-unused-vars': [
        vars: 'all',
        args: 'none',
        ignoreRestSiblings: true,
    'import/order': [
        alphabetize: { order: 'asc', caseInsensitive: false },
        'newlines-between': 'always-and-inside-groups',
        warnOnUnassignedImports: true,
    'import/no-extraneous-dependencies': [
        devDependencies: [
// tsconfig.json

  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
// .prettierrc

  "singleQuote": true,
  "arrowParens": "avoid",
  "trailingComma": "es5",
  "tabWidth": 2,
  "useTabs": false
// .lintstagedrc.js

const path = require('path');

module.exports = {
  // Type check TypeScript files
  '**/*.(ts|tsx)': () => 'yarn tsc --noEmit',

  // Lint then format TypeScript and JavaScript files
  '**/*.(ts|tsx|js|jsx)': filenames => [
    `next lint --fix --file ${filenames
      .map(f => path.relative(process.cwd(), f))
      .join(' --file ')}`,
    `yarn prettier --write ${filenames.join(' ')}`,

  // Format MarkDown and JSON
  '**/*.(md|json)': filenames => `yarn prettier --write ${filenames.join(' ')}`,

Husky and pre commit hook

In previous section we installed husky and we need to init it.

yarn husky install


yarn husky add .husky/pre-commit "yarn lint-staged"

This adds a git pre-commit hook and it will execute lint-staged(run eslint, prettier etc.) for staged files every time right before commit.

Leave a Reply

Your email address will not be published. Required fields are marked *