Change from ESLint and Prettier to BiomeJS

How to Migrate from ESLint and Prettier to BiomeJS

Steps

Add BiomeJS

pnpm add -d @biomejs/biome

List all ESLint & Prettier dependencies and remove them

find . -name "package.json" -not -path "*/node_modules/*" -exec jq -r '.dependencies + .devDependencies | keys[] | select(contains("eslint") or contains("prettier"))' {} \; | sort -u | xargs pnpm remove -r

This command combines find with jq for JSON processing - for more advanced file processing techniques, see my guide on recursive file operations.

  • This finds all package.json files in the project directory (you may have more than 1 if you're using a monorepo)
  • It runs jq, which is a json query package to find all files that contains "eslint" or "prettier", most plugins also contain the same words in the name.
  • sorts and creates a unique list
  • uses xargs with pnpm to remove the dependencies recursively.

Create a Biome Configuration File

pnpx @biomejs/biome init

This will create a basic configuration file.

I use the following file in most projects

{
  "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
  "organizeImports": {
    "enabled": true
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "suspicious": {
        "noExplicitAny": "error",
        "noImplicitAnyLet": "error"
      },
      "style": {
        "useImportType": "error",
        "noNonNullAssertion": "error"
      },
      "complexity": {
        "noForEach": "error",
        "noUselessEmptyExport": "error"
      }
    }
  },
  "formatter": {
    "enabled": true,
    "formatWithErrors": false,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100,
    "ignore": [
      "**/node_modules/**",
      "**/dist/**",
      "**/build/**",
      "**/.sst/**",
      "**/cdk.out/**",
      "**/coverage/**",
      "**/*.d.ts",
      "tailwindcss"
    ]
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "single",
      "trailingCommas": "es5",
      "semicolons": "always",
      "quoteProperties": "asNeeded",
      "arrowParentheses": "asNeeded",
      "bracketSpacing": true,
      "bracketSameLine": false
    }
  },
  "files": {
    "ignore": [
      "**/node_modules/**",
      "**/dist/**",
      "**/build/**",
      "**/.sst/**",
      "**/cdk.out/**",
      "**/coverage/**",
      "**/.next/**",
      "**/*.d.ts"
    ]
  },
  "vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": true
  },
  "overrides": []
}

Update your root package.json scripts

"scripts": {
    "format": "biome format --write .",
    "lint": "biome lint --write .",
    "check": "biome check .",
}

Remove any old configuration files This needs to be done manually as the number of configuration scripts and types are bountiful! Also, helps with going through the configs and updating biomejs as needed.

Run checks, and commit!

pnpm check

Have fun making the fixes. 😅

Also, make sure you're updating any CI/CD pipeline configs, if relevant!

Usecase

The (recent) updates on ESLint 9 has made the dev experience quite pathetic because of broken compatibility. I honestly found it a lot easier to migrate away from the ecosystem to something like biome a lot easier! For another migration guide, see Migrate your Remix app from Vercel to SST.dev which covers moving deployment platforms.