skillby sgcarstrends

biome-config

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.

Installs: 0
Used in: 1 repos
Updated: 1d ago
$npx ai-builder add skill sgcarstrends/biome-config

Installs to .claude/skills/biome-config/

# 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

```json
// 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

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

### Test Files Configuration

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

## Common Commands

### Check Code

```bash
# 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

```bash
# 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

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

### CI Mode

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

## Linting Rules

### Enabling/Disabling Rules

**Disable a rule globally:**
```json
{
  "linter": {
    "rules": {
      "suspicious": {
        "noExplicitAny": "off"
      }
    }
  }
}
```

**Change severity:**
```json
{
  "linter": {
    "rules": {
      "suspicious": {
        "noExplicitAny": "warn"  // error, warn, off
      }
    }
  }
}
```

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

**Disable for entire file:**
```typescript
/* biome-ignore lint/suspicious/noExplicitAny: Test file */
```

### Recommended Rules

**Enable all recommended:**
```json
{
  "linter": {
    "rules": {
      "recommended": true
    }
  }
}
```

**Enable specific categories:**
```json
{
  "linter": {
    "rules": {
      "recommended": false,
      "correctness": {
        "recommended": true
      },
      "security": {
        "recommended": true
      },
      "performance": {
        "recommended": true
      }
    }
  }
}
```

## Formatting Configuration

### JavaScript/TypeScript

```json
{
  "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

```json
{
  "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

```json
{
  "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:
```typescript
// 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:

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

### Git-Aware Processing

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

## Ignoring Files

### Via Configuration

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

### Via .gitignore

With `useIgnoreFile: true`, Biome respects `.gitignore`.

### Inline Ignore

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

## Package.json Scripts

```json
{
  "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

```json
// .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

```bash
# 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

```bash
# 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

```bash
npx @biomejs/biome migrate eslint --write
```

### 4. Update Scripts

Replace in `package.json`:
```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

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

### Custom Rule Severity

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

## CI Integration

### GitHub Actions

```yaml
# .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

- Biome Documentation: https://biomejs.dev
- Migration Guide: https://biomejs.dev/guides/migrate-eslint-prettier
- Rules Reference: https://biomejs.dev/linter/rules
- Related files:
  - `biome.json` - Root configuration
  - Root CLAUDE.md - Code style guidelines

## 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

Quick Install

$npx ai-builder add skill sgcarstrends/biome-config

Details

Type
skill
Slug
sgcarstrends/biome-config
Created
4d ago