Claude Code Plugins

Community-maintained marketplace

Feedback

Update Biome linting rules, formatting configs, and import organization settings. Use when adding new lint rules, customizing code style, or fixing workspace-specific linting issues.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name biome-config
description Update Biome linting rules, formatting configs, and import organization settings. Use when adding new lint rules, customizing code style, or fixing workspace-specific linting issues.
allowed-tools Read, Edit, Bash, Grep, Glob

Biome Configuration Skill

This skill helps you configure and customize Biome for linting and formatting across the monorepo.

When to Use This Skill

  • Adding new linting rules
  • Customizing code formatting
  • Configuring import organization
  • Fixing linting errors across the codebase
  • Setting up workspace-specific rules
  • Debugging Biome configuration issues
  • Migrating from ESLint/Prettier

Biome Overview

Biome is an all-in-one toolchain for web projects that provides:

  • Linting: Fast, opinionated linting
  • Formatting: Consistent code formatting
  • Import Organization: Automatic import sorting

The project uses Biome instead of ESLint and Prettier for better performance.

Configuration Structure

sgcarstrends/
├── biome.json                 # Root Biome config
├── apps/
│   ├── api/
│   │   └── biome.json        # API-specific config (extends root)
│   └── web/
│       └── biome.json        # Web-specific config (extends root)
└── packages/
    └── database/
        └── biome.json        # Database-specific config

Root Configuration

// biome.json
{
  "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
  "vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": true,
    "defaultBranch": "main"
  },
  "files": {
    "ignoreUnknown": false,
    "ignore": [
      "node_modules",
      "dist",
      "build",
      ".next",
      ".turbo",
      "coverage",
      ".sst"
    ]
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100,
    "lineEnding": "lf"
  },
  "organizeImports": {
    "enabled": true
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "complexity": {
        "noExtraBooleanCast": "error",
        "noMultipleSpacesInRegularExpressionLiterals": "error",
        "noUselessCatch": "error",
        "noUselessConstructor": "error",
        "noUselessEmptyExport": "error",
        "noWith": "error"
      },
      "correctness": {
        "noConstAssign": "error",
        "noConstantCondition": "error",
        "noEmptyCharacterClassInRegex": "error",
        "noEmptyPattern": "error",
        "noGlobalObjectCalls": "error",
        "noInvalidConstructorSuper": "error",
        "noInvalidNewBuiltin": "error",
        "noNonoctalDecimalEscape": "error",
        "noPrecisionLoss": "error",
        "noSelfAssign": "error",
        "noSetterReturn": "error",
        "noSwitchDeclarations": "error",
        "noUndeclaredVariables": "error",
        "noUnreachable": "error",
        "noUnreachableSuper": "error",
        "noUnsafeFinally": "error",
        "noUnsafeOptionalChaining": "error",
        "noUnusedLabels": "error",
        "noUnusedVariables": "error",
        "useIsNan": "error",
        "useValidForDirection": "error",
        "useYield": "error"
      },
      "security": {
        "noDangerouslySetInnerHtml": "error",
        "noDangerouslySetInnerHtmlWithChildren": "error"
      },
      "style": {
        "noArguments": "error",
        "noVar": "error",
        "useConst": "error",
        "useTemplate": "error"
      },
      "suspicious": {
        "noAsyncPromiseExecutor": "error",
        "noCatchAssign": "error",
        "noClassAssign": "error",
        "noCommentText": "error",
        "noCompareNegZero": "error",
        "noDebugger": "error",
        "noDoubleEquals": "error",
        "noDuplicateCase": "error",
        "noDuplicateClassMembers": "error",
        "noDuplicateObjectKeys": "error",
        "noDuplicateParameters": "error",
        "noEmptyBlockStatements": "error",
        "noExplicitAny": "warn",
        "noExtraNonNullAssertion": "error",
        "noFallthroughSwitchClause": "error",
        "noFunctionAssign": "error",
        "noGlobalAssign": "error",
        "noImportAssign": "error",
        "noMisleadingCharacterClass": "error",
        "noMisleadingInstantiator": "error",
        "noPrototypeBuiltins": "error",
        "noRedeclare": "error",
        "noShadowRestrictedNames": "error",
        "noUnsafeDeclarationMerging": "error",
        "noUnsafeNegation": "error",
        "useGetterReturn": "error",
        "useValidTypeof": "error"
      }
    }
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "double",
      "jsxQuoteStyle": "double",
      "quoteProperties": "asNeeded",
      "trailingCommas": "es5",
      "semicolons": "always",
      "arrowParentheses": "always",
      "bracketSpacing": true,
      "bracketSameLine": false
    }
  }
}

Workspace-Specific Configuration

Apps Configuration

// apps/web/biome.json
{
  "extends": ["../../biome.json"],
  "linter": {
    "rules": {
      "suspicious": {
        "noExplicitAny": "off"  // Allow 'any' in web app for flexibility
      }
    }
  }
}

Test Files Configuration

// Override for test files (if needed)
{
  "overrides": [
    {
      "include": ["**/__tests__/**", "**/*.test.ts", "**/*.spec.ts"],
      "linter": {
        "rules": {
          "suspicious": {
            "noExplicitAny": "off"
          }
        }
      }
    }
  ]
}

Common Commands

Check Code

# Check all files
pnpm biome check .

# Check specific directory
pnpm biome check apps/web

# Check and apply safe fixes
pnpm biome check --write .

# Check only linting
pnpm biome lint .

# Check only formatting
pnpm biome format .

Format Code

# Format all files
pnpm biome format --write .

# Format specific files
pnpm biome format --write apps/web/src/**/*.ts

# Check formatting without writing
pnpm biome format .

Organize Imports

# Organize imports
pnpm biome check --organize-imports-enabled=true --write .

CI Mode

# Check without modifying files (for CI)
pnpm biome ci .

Linting Rules

Enabling/Disabling Rules

Disable a rule globally:

{
  "linter": {
    "rules": {
      "suspicious": {
        "noExplicitAny": "off"
      }
    }
  }
}

Change severity:

{
  "linter": {
    "rules": {
      "suspicious": {
        "noExplicitAny": "warn"  // error, warn, off
      }
    }
  }
}

Disable inline:

// biome-ignore lint/suspicious/noExplicitAny: Legacy code needs refactoring
function legacy(data: any) {
  // ...
}

Disable for entire file:

/* biome-ignore lint/suspicious/noExplicitAny: Test file */

Recommended Rules

Enable all recommended:

{
  "linter": {
    "rules": {
      "recommended": true
    }
  }
}

Enable specific categories:

{
  "linter": {
    "rules": {
      "recommended": false,
      "correctness": {
        "recommended": true
      },
      "security": {
        "recommended": true
      },
      "performance": {
        "recommended": true
      }
    }
  }
}

Formatting Configuration

JavaScript/TypeScript

{
  "javascript": {
    "formatter": {
      "quoteStyle": "double",           // "single" or "double"
      "jsxQuoteStyle": "double",
      "quoteProperties": "asNeeded",    // "asNeeded" or "preserve"
      "trailingCommas": "es5",          // "none", "es5", or "all"
      "semicolons": "always",           // "always" or "asNeeded"
      "arrowParentheses": "always",     // "always" or "asNeeded"
      "bracketSpacing": true,
      "bracketSameLine": false
    }
  }
}

Line Width and Indentation

{
  "formatter": {
    "indentStyle": "space",    // "space" or "tab"
    "indentWidth": 2,          // Number of spaces
    "lineWidth": 100,          // Max line length
    "lineEnding": "lf"         // "lf", "crlf", or "cr"
  }
}

Import Organization

Configuration

{
  "organizeImports": {
    "enabled": true
  }
}

Import Groups

Biome automatically organizes imports into groups:

  1. Built-in modules (e.g., fs, path)
  2. External modules (e.g., react, next)
  3. Internal modules (e.g., @/components, ~/utils)
  4. Relative imports (e.g., ./utils, ../types)

Example:

// Before
import { Button } from "./components/button";
import { useState } from "react";
import path from "path";
import { db } from "@/lib/db";

// After
import path from "path";

import { useState } from "react";

import { db } from "@/lib/db";

import { Button } from "./components/button";

Git Integration

Git Hooks with Husky

Biome integrates with git hooks:

// .husky/pre-commit
pnpm biome check --write --staged

Git-Aware Processing

{
  "vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": true,     // Respect .gitignore
    "defaultBranch": "main"
  }
}

Ignoring Files

Via Configuration

{
  "files": {
    "ignore": [
      "node_modules",
      "dist",
      "build",
      ".next",
      ".turbo",
      "coverage",
      ".sst",
      "**/*.config.js",
      "migrations/**"
    ]
  }
}

Via .gitignore

With useIgnoreFile: true, Biome respects .gitignore.

Inline Ignore

// biome-ignore format: Auto-generated code
const generated = "...";

Package.json Scripts

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

VS Code Integration

Install Extension

  1. Install "Biome" extension
  2. Configure as default formatter

Settings

// .vscode/settings.json
{
  "[typescript]": {
    "editor.defaultFormatter": "biomejs.biome",
    "editor.formatOnSave": true
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "biomejs.biome",
    "editor.formatOnSave": true
  },
  "[javascript]": {
    "editor.defaultFormatter": "biomejs.biome",
    "editor.formatOnSave": true
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "biomejs.biome",
    "editor.formatOnSave": true
  },
  "[json]": {
    "editor.defaultFormatter": "biomejs.biome",
    "editor.formatOnSave": true
  },
  "editor.codeActionsOnSave": {
    "quickfix.biome": "explicit",
    "source.organizeImports.biome": "explicit"
  }
}

Migration from ESLint/Prettier

1. Remove Old Tools

# Remove ESLint
pnpm remove -r eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin

# Remove Prettier
pnpm remove -r prettier

# Remove config files
rm .eslintrc.json .prettierrc .prettierignore

2. Install Biome

# Already installed in project
pnpm add -D -w @biomejs/biome

3. Migrate Configuration

Convert ESLint rules to Biome:

  • Check Biome documentation for equivalent rules
  • Some rules may not have direct equivalents
  • Use biome migrate eslint for automated migration
npx @biomejs/biome migrate eslint --write

4. Update Scripts

Replace in package.json:

{
  "scripts": {
    "lint": "biome check .",      // was: eslint .
    "format": "biome format --write ."  // was: prettier --write .
  }
}

Troubleshooting

Rule Conflicts

Issue: Rule seems to contradict another Solution: Check rule documentation, disable one if needed

Performance Issues

Issue: Biome is slow on large codebase Solutions:

  1. Check files.ignore is properly set
  2. Run on specific directories
  3. Use --max-diagnostics to limit output

Format Not Applied

Issue: Files not formatting on save Solutions:

  1. Check VS Code extension is installed
  2. Verify editor.defaultFormatter is set to Biome
  3. Check biome.json is in workspace root

Import Organization Not Working

Issue: Imports not organizing Solutions:

  1. Verify organizeImports.enabled: true
  2. Run explicitly: biome check --organize-imports-enabled=true --write .
  3. Check for syntax errors in file

Advanced Configuration

Per-File Overrides

{
  "overrides": [
    {
      "include": ["**/*.config.ts"],
      "linter": {
        "rules": {
          "suspicious": {
            "noExplicitAny": "off"
          }
        }
      }
    },
    {
      "include": ["apps/api/**/*.ts"],
      "formatter": {
        "lineWidth": 120
      }
    }
  ]
}

Custom Rule Severity

{
  "linter": {
    "rules": {
      "correctness": {
        "noUnusedVariables": "error"
      },
      "style": {
        "useConst": "warn"
      },
      "suspicious": {
        "noExplicitAny": "off"
      }
    }
  }
}

CI Integration

GitHub Actions

# .github/workflows/lint.yml
name: Lint

on: [push, pull_request]

jobs:
  biome:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v2
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "pnpm"
      - run: pnpm install
      - run: pnpm biome ci .

References

Best Practices

  1. Use Root Config: Define common rules in root biome.json
  2. Extend in Workspaces: Extend root config for workspace-specific rules
  3. Git Integration: Enable VCS integration for .gitignore support
  4. Pre-commit Hooks: Run Biome on staged files
  5. CI Checks: Use biome ci in continuous integration
  6. Inline Ignores: Use sparingly and with clear comments
  7. Consistent Formatting: Apply formatting across entire codebase
  8. Regular Updates: Keep Biome updated for new rules and fixes