> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jtbdos.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Switch to ESLint

> How to change the default linter to ESLint.

export const Authors = ({data}) => {
  const baseUrl = typeof window !== 'undefined' && window.location.origin.includes('localhost') ? '' : 'https://raw.githubusercontent.com/haydenbleasel/JTBDOS/refs/heads/main/docs';
  return <div style={{
    marginBottom: '3rem',
    display: 'flex',
    flexDirection: 'column',
    gap: '0.5rem'
  }}>
      <span style={{
    color: 'rgb(107, 114, 128)',
    fontSize: '0.875rem'
  }}>Co-authored by</span>
      <div style={{
    display: 'flex',
    flexWrap: 'wrap',
    alignItems: 'center',
    gap: '0.5rem'
  }}>
        {data.map(author => <div key={author.name} style={{
    padding: '0.75rem',
    paddingRight: '1rem',
    display: 'inline-flex',
    alignItems: 'center',
    gap: '0.75rem',
    fontWeight: 'normal',
    position: 'relative',
    ringWidth: '2px',
    ringColor: 'transparent',
    borderRadius: '0.75rem',
    backgroundColor: 'white',
    border: '1px solid rgba(0,0,0,0.1)',
    overflow: 'hidden'
  }}>
            <div style={{
    position: 'relative'
  }}>
              <div style={{
    overflow: 'hidden',
    border: '1px solid #e5e7eb',
    borderRadius: '9999px',
    width: '2rem',
    height: '2rem'
  }}>
                <img style={{
    margin: 0,
    width: '100%',
    height: '100%',
    objectFit: 'cover'
  }} src={`${baseUrl}/images/authors/${author.company.id}/${author.user.id}.jpg`} alt="" width={32} height={32} />
              </div>
              <div style={{
    position: 'absolute',
    border: '1px solid white',
    overflow: 'hidden',
    borderRadius: '9999px',
    objectFit: 'cover',
    width: '1rem',
    height: '1rem',
    right: '-0.25rem',
    bottom: '-0.25rem'
  }}>
                <img style={{
    margin: 0,
    width: '100%',
    height: '100%',
    objectFit: 'cover'
  }} src={`${baseUrl}/images/authors/${author.company.id}/logo.jpg`} alt="" width={16} height={16} />
              </div>
            </div>
            <div style={{
    display: 'flex',
    flexDirection: 'column'
  }}>
              <span style={{
    fontWeight: 600,
    lineHeight: 1.25,
    fontSize: '13px',
    letterSpacing: '-0.01em'
  }}>
                {author.user.name}
              </span>
              <span style={{
    color: 'rgb(107, 114, 128)',
    lineHeight: 1.25,
    fontSize: '11px'
  }}>
                {author.company.name}
              </span>
            </div>
          </div>)}
      </div>
    </div>;
};

<Authors
  data={[{
user: {
name: 'Hayden Bleasel',
id: 'haydenbleasel',
},
company: {
name: 'JTBDOS',
id: 'JTBDOS',
},
}, {
user: {
name: 'Nicholas C. Zakas',
id: 'slicknet',
},
company: {
name: 'ESLint',
id: 'eslint',
},
}]}
/>

Here's how to switch from Biome to [ESLint](https://eslint.org). In this example, we'll also add the Next.js and React plugins, as well as the new ESLint Flat Config.

## 1. Swap out the required dependencies

First, uninstall the existing dependencies from the root `package.json` file...

```sh Terminal
pnpm remove -w @biomejs/biome ultracite
```

...and install the new ones:

```sh Terminal
pnpm add -w -D eslint eslint-plugin-next eslint-plugin-react eslint-plugin-react-hooks typescript-eslint
```

## 2. Configure ESLint

Delete the existing `biome.json` file in the root of the project, and create a new `eslint.config.mjs` file:

```js eslint.config.mjs
import react from 'eslint-plugin-react';
import next from '@next/eslint-plugin-next';
import hooks from 'eslint-plugin-react-hooks';
import ts from 'typescript-eslint'

export default [
  ...ts.configs.recommended,
  {
    ignores: ['**/.next'],
  },
  { 
    files: ['**/*.ts', '**/*.tsx'],
    plugins: {
      react: react,
      'react-hooks': hooks,
      '@next/next': next,
    },
    rules: {
      ...react.configs['jsx-runtime'].rules,
      ...hooks.configs.recommended.rules,
      ...next.configs.recommended.rules,
      ...next.configs['core-web-vitals'].rules,
      '@next/next/no-img-element': 'error',
    },
  },
]
```

## 3. Install the ESLint VSCode extension

<Tip>
  This is generally installed if you selected "JavaScript" as a language to support when you first set up Visual Studio Code.
</Tip>

Install the [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) VSCode extension to get linting and formatting support in your editor.

## 4. Update your `.vscode/settings.json` file

Add the following to your `.vscode/settings.json` file to match the following:

```json .vscode/settings.json
{
  "editor.codeActionsOnSave": {
    "source.fixAll": true,
    "source.fixAll.eslint": true
  },
  "editor.defaultFormatter": "dbaeumer.vscode-eslint",
  "editor.formatOnPaste": true,
  "editor.formatOnSave": true,
  "emmet.showExpandedAbbreviation": "never",
  "prettier.enable": true,
  "tailwindCSS.experimental.configFile": "./packages/tailwind-config/config.ts",
  "typescript.tsdk": "node_modules/typescript/lib"
}
```

## 5. Re-enable the `lint` script

As Next.js uses ESLint for linting, we can re-enable the `lint` script in the root `package.json` files. In each of the Next.js apps, update the `package.json` file to include the following:

```json apps/app/package.json {3}
{
  "scripts": {
    "lint": "next lint"
  }
}
```
