biome
Scannednpx machina-cli add skill DigitalPine/claude-skills/biome --openclawBiome Setup and Configuration
Expert guidance for setting up and configuring Biome linter and formatter in JavaScript/TypeScript projects, with emphasis on handling unsafe fixes for routine development workflows.
When to Use This Skill
- Setting up Biome in new or existing projects
- Auditing existing Biome configurations
- Checking if Biome config follows best practices
- Configuring Biome for Next.js, React, or vanilla JS/TS projects
- Understanding and applying unsafe fixes
- Migrating from ESLint + Prettier
- Optimizing Biome for team workflows
- Fixing Biome configuration issues
- Reviewing unsafe fix strategy
- Troubleshooting formatting or linting problems
Core Principles
Unsafe fixes in routine workflow - While Biome marks certain fixes as "unsafe" because they may change code semantics, many of these (like removing unused imports/variables) are safe enough for routine development and should be part of standard lint/format workflows.
Single tool simplicity - Biome replaces both ESLint and Prettier with a single, fast tool. Configure once, use everywhere.
Installation
New Projects
For Next.js 16+ projects, use the built-in flag:
pnpm create next-app@latest --biome my-app
Existing Projects
Install with exact version pinning and initialize:
pnpm add -D -E @biomejs/biome
npx @biomejs/biome init
Why these steps:
-Eflag ensures consistent behavior across team members and CIinitgeneratesbiome.jsonwith correct schema version and modern syntax
Then customize the generated config with your project's needs (see Configuration section below).
Configuration File Structure
Biome uses biome.json (or biome.jsonc for comments) in project root.
Basic Configuration
After running biome init and biome migrate, customize the generated config:
{
"$schema": "https://biomejs.dev/schemas/[VERSION]/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"ignoreUnknown": true,
"includes": ["src/**", "app/**", "lib/**", "*.ts", "*.js"]
},
"formatter": {
"enabled": true,
"indentStyle": "tab",
"lineWidth": 100
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"noUnusedImports": {
"level": "error",
"fix": "safe"
},
"noUnusedVariables": {
"level": "error",
"fix": "safe"
}
},
"style": {
"useConst": {
"level": "error",
"fix": "safe"
},
"useTemplate": {
"level": "error",
"fix": "safe"
}
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"semicolons": "always",
"trailingCommas": "all",
"arrowParentheses": "asNeeded"
}
},
"assist": {
"enabled": true,
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}
Note: The rule overrides in the linter.rules section change commonly-used rules from "unsafe" to "safe" fixes:
noUnusedImports- Automatically removes unused importsnoUnusedVariables- Automatically prefixes unused variables with underscoreuseConst- Automatically changeslettoconstfor never-reassigned variablesuseTemplate- Automatically converts string concatenation to template literals
These fixes will now apply on editor save and during normal --write operations without needing the --unsafe flag. See "Decision Framework" section for details on when to use these overrides.
Understanding Unsafe Fixes
What Makes a Fix "Unsafe"?
Biome marks fixes as unsafe when they might change code semantics or behavior:
- noUnusedImports: Removes unused imports (unsafe because might remove associated comments or affect type-only imports)
- noUnusedVariables: Prefixes unused variables with underscore (unsafe because doesn't remove, just silences)
- Other transformation rules that modify logic
Safe vs Unsafe Philosophy
Safe fixes are guaranteed not to change program behavior and can auto-apply on save.
Unsafe fixes might alter semantics and require the --unsafe flag.
"Safe Enough" Unsafe Fixes
For routine development, these unsafe fixes are typically safe to apply regularly:
- noUnusedImports - Removing unused imports is almost always desired
- noUnusedVariables - Flagging unused variables catches bugs
- organizeImports (via assist) - Sorting imports improves consistency
Package.json Scripts
Recommended Scripts
{
"scripts": {
"format": "biome format --write .",
"lint": "biome lint --write .",
"check": "biome check --write .",
"check:ci": "biome ci ."
}
}
Script purposes:
format- Format files only (dev workflow)lint- Lint and auto-fix issues (dev workflow)check- Combined format + lint + organize imports (dev workflow)check:ci- CI-safe check that fails without modifying files
Note on removed scripts:
format:checkandlint:checkare redundant -biome cihandles all CI checking- For local read-only checks, use
biome ci .directly
With Unsafe Fixes (Optional)
If you haven't configured individual rules as "safe" (see Configuration section), add --unsafe to dev scripts:
{
"scripts": {
"lint": "biome lint --write --unsafe .",
"check": "biome check --write --unsafe ."
}
}
Only needed if:
- You want unused imports/variables removed automatically
- Rules like
noUnusedImportsstill marked as "unsafe" in your config
Usage Patterns
# Daily development - lint and auto-fix
pnpm lint
# Pre-commit/PR - comprehensive check with all fixes
pnpm check
# CI - verify only, no changes
pnpm check:ci
# Quick format only
pnpm format
Next.js Integration
When using Biome with Next.js, disable ESLint during builds:
// next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
eslint: {
// Using Biome instead of ESLint
ignoreDuringBuilds: true,
},
};
export default nextConfig;
Editor Integration
VS Code
Install extension: biomejs.biome
Add to .vscode/settings.json:
{
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
},
"[javascriptreact]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true
}
}
Important: Editor integration applies only safe fixes on save. Unsafe fixes require manual CLI execution with --unsafe flag.
Migration from ESLint + Prettier
Step-by-Step
-
Install Biome
pnpm add -D -E @biomejs/biome npx @biomejs/biome init -
Remove old tooling
pnpm remove eslint prettier eslint-config-next eslint-config-prettier -
Delete config files
.eslintrc.jsonor.eslintrc.js.prettierrcorprettier.config.js.prettierignore
-
Update package.json scripts (see Scripts section above)
-
Format codebase
pnpm format pnpm lint # includes --unsafe if configured -
Update Next.js config (if applicable, see Next.js Integration)
-
Commit changes
git add . git commit -m "Migrate from ESLint+Prettier to Biome"
Decision Framework
When to Use Unsafe Fixes
✅ Use --unsafe flag for:
- Daily development linting (
pnpm lint) - Pre-commit cleanup (
pnpm check) - Removing unused imports/variables
- Team workflows where code review catches issues
❌ Skip --unsafe flag for:
- CI checks (
pnpm check:ci) - Automated tools with no human review
- Generated code
- Legacy code with uncertain test coverage
When to Configure Individual Rule Safety
Recommended: Override common "safe enough" unsafe rules
These rules are marked unsafe by default but are almost always safe to apply automatically:
{
"linter": {
"rules": {
"recommended": true,
"correctness": {
"noUnusedImports": {
"level": "error",
"fix": "safe"
},
"noUnusedVariables": {
"level": "error",
"fix": "safe"
}
},
"style": {
"useConst": {
"level": "error",
"fix": "safe"
},
"useTemplate": {
"level": "error",
"fix": "safe"
}
}
}
}
}
Impact: These fixes will now apply on editor save and in normal --write operations without needing --unsafe flag.
Why these are safe enough:
noUnusedImports- Removing unused imports is desired 98% of the timenoUnusedVariables- Only prefixes with underscore, doesn't remove codeuseConst- Changinglettoconstfor never-reassigned variables improves code qualityuseTemplate- Template literals are preferred modern syntax
Common Patterns
Monorepo Configuration
Root biome.json with shared settings:
{
"$schema": "https://biomejs.dev/schemas/[VERSION]/schema.json",
"extends": ["./packages/*/biome.json"],
"files": {
"ignoreUnknown": true
}
}
Package-specific overrides:
{
"extends": ["../../biome.json"],
"files": {
"includes": ["src/**", "test/**"]
}
}
Project-Specific Ignore Patterns
Use includes with negation patterns (modern syntax):
{
"files": {
"includes": [
"**",
"!**/node_modules/**",
"!**/.next/**",
"!**/dist/**",
"!**/build/**",
"!**/coverage/**",
"!**/*.generated.ts",
"!**/__snapshots__/**"
]
}
}
Note: The deprecated ignore field will cause configuration errors. Use includes with exclamation mark (!) prefix for exclusions.
Gradual Adoption
Start with recommended rules, then add more as codebase improves:
{
"linter": {
"rules": {
"recommended": true,
"correctness": {
"noUnusedImports": "error",
"noUnusedVariables": "warn" // Warn first, error later
}
}
}
}
Troubleshooting
Issue: "Found an unknown key ignore" error
Symptom: Biome check/lint/format fails with deserialize error about unknown ignore key.
Cause: Config uses deprecated files.ignore field (pre-2.2 syntax). Modern biome uses files.includes with negation patterns.
Solution - Option 1 (Auto-fix):
# Let biome migrate deprecated syntax automatically
npx @biomejs/biome migrate --write
# Verify config is fixed
npx @biomejs/biome check .
Solution - Option 2 (Manual fix):
Update biome.json to use modern syntax:
// OLD (deprecated - causes error)
"files": {
"ignore": ["node_modules/**", "dist/**"]
}
// NEW (modern - works)
"files": {
"includes": ["**", "!**/node_modules/**", "!**/dist/**"]
}
When you see this:
- Copying old config examples from Stack Overflow, old docs, etc.
- Using config written for biome < 2.2
- After upgrading biome versions
Issue: Biome not formatting in editor
- Ensure Biome extension installed
- Check
.vscode/settings.jsonhas correctdefaultFormatter - Restart editor after installing extension
- Verify
biome.jsonexists and is valid
Issue: Unused imports not being removed
- Check that
noUnusedImportsis enabled (included inrecommended) - Use
--unsafeflag:pnpm biome lint --write --unsafe . - Verify
assist.actions.source.organizeImportsis enabled
Issue: Different formatting between CLI and editor
- Ensure exact Biome version pinned with
-Eflag - Check no conflicting Prettier extension active
- Run
npx @biomejs/biome versionto verify version - Clear editor cache and restart
Issue: Build fails with ESLint errors
- Add
eslint: { ignoreDuringBuilds: true }tonext.config.js - Remove ESLint dependencies
- Ensure Biome scripts in package.json
Issue: Git shows too many changes after migration
Expected! Biome has different formatting defaults than Prettier. Do migration in dedicated commit:
pnpm format
pnpm lint --unsafe # or pnpm check --unsafe
git add .
git commit -m "chore: apply Biome formatting"
Resources
- Official docs: https://biomejs.dev
- Configuration guide: https://next.biomejs.dev/guides/configure-biome/
- Linter rules: https://biomejs.dev/linter/rules/
- Next.js integration: https://next.biomejs.dev/linter/domains/#next
Version Notes
This skill is current as of Biome 2.3+ (November 2025). Check official docs for latest features.
Source
git clone https://github.com/DigitalPine/claude-skills/blob/main/plugins/biome/skills/biome/SKILL.mdView on GitHub Overview
Biome is a single-tool linter/formatter for JavaScript and TypeScript projects. This skill covers installing Biome, auditing configs, migrating from ESLint+Prettier, and configuring safe fixes, including Next.js, VS Code, and script setup, with emphasis on version pinning.
How This Skill Works
Biome replaces ESLint and Prettier with one fast tool and uses a project root biome.json (or biome.jsonc) to define rules, formatting, and fixes. You install a pinned version, run biome init to generate a proper schema, optionally migrate from ESLint+Prettier, and then apply fixes—safe by default, with unsafe fixes controlled by the config for development workflows.
When to Use It
- Setting up Biome in a new or existing JavaScript/TypeScript project
- Auditing and validating an existing Biome configuration
- Migrating from ESLint + Prettier to Biome
- Configuring Biome for Next.js, React, or vanilla JS/TS projects and VS Code
- Optimizing team workflows while safely handling unsafe fixes
Quick Start
- Step 1: Install Biome with exact version pin: pnpm add -D -E @biomejs/biome
- Step 2: Initialize Biome in your project: npx @biomejs/biome init
- Step 3: Customize biome.json (or run biome migrate) to fit your project needs and enable safe fixes
Best Practices
- Pin Biome version exactly (use -E) to ensure consistent behavior across teams and CI
- Run biome init and then biome migrate to generate and update biome.json
- Prefer safe fixes by default; review unsafe fixes before applying in CI or on save
- Configure Next.js integration, VS Code setup, and script sections in biome.json
- Review and tailor linter.rules (recommended/correctness/style) to match team standards
Example Use Cases
- New Next.js 16+ project initialized with Biome via pnpm create next-app@latest --biome my-app
- Migrate an ESLint+Prettier project to Biome and consolidate tooling behind a single config
- Audit an existing biome.json and enable safe fixes for noUnusedImports and noUnusedVariables
- Configure VS Code to apply Biome fixes on save and align editor settings with biome.json
- Set up CI to install exact Biome version and run with -E to ensure consistency