Using Biome for fast, unified code formatting and linting - a modern alternative to ESLint and Prettier
This skill covers using Biome, a fast all-in-one toolchain for formatting and linting JavaScript/TypeScript code.
Biome is a performant toolchain that provides:
npm install --save-dev @biomejs/biome
Create biome.json in your project root:
{
"$schema": "https://biomejs.dev/schemas/1.5.3/schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"formatter": {
"enabled": true,
"formatWithErrors": false,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100,
"lineEnding": "lf"
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"trailingComma": "es5",
"semicolons": "always",
"arrowParentheses": "always",
"bracketSpacing": true,
"jsxQuoteStyle": "double"
}
}
}
{
"scripts": {
"format": "biome format --write .",
"format:check": "biome format .",
"lint": "biome lint .",
"lint:fix": "biome lint --apply .",
"check": "biome check --apply .",
"ci": "biome ci ."
}
}
Script explanations:
format - Format all files in placeformat:check - Check if files are formatted (CI)lint - Show linting errorslint:fix - Fix auto-fixable issuescheck - Format + lint + organize imports (recommended)ci - Check everything without modifying files (for CI)# Format all files
npm run format
# Format specific files
npx biome format --write src/
# Check formatting without modifying
npx biome format src/
# Lint all files
npm run lint
# Lint and fix
npm run lint:fix
# Lint specific files
npx biome lint src/
# Format, lint, and organize imports
npm run check
# Check without modifying (for CI)
npm run ci
{
"files": {
"include": ["src/**/*.ts", "src/**/*.tsx"],
"ignore": [
"node_modules",
"dist",
"build",
".sst",
"*.config.js"
]
}
}
{
"overrides": [
{
"include": ["*.test.ts", "*.spec.ts"],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off"
}
}
}
}
]
}
{
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
}
}
{
"linter": {
"rules": {
"recommended": true,
"complexity": {
"noExcessiveCognitiveComplexity": "warn",
"noForEach": "off"
},
"style": {
"noNegationElse": "error",
"useTemplate": "warn"
},
"suspicious": {
"noExplicitAny": "warn",
"noArrayIndexKey": "warn"
}
}
}
}
Complexity:
Correctness:
Performance:
Security:
Style:
Suspicious:
{
"formatter": {
"enabled": true,
"formatWithErrors": false,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100,
"lineEnding": "lf"
}
}
{
"javascript": {
"formatter": {
"quoteStyle": "double",
"jsxQuoteStyle": "double",
"quoteProperties": "asNeeded",
"trailingComma": "all",
"semicolons": "always",
"arrowParentheses": "always",
"bracketSpacing": true,
"bracketSameLine": false
}
}
}
{
"organizeImports": {
"enabled": true
}
}
Biome will:
Install "Biome" extension from VSCode marketplace.
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
},
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
}
}
npm install --save-dev husky lint-staged
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"biome check --apply --no-errors-on-unmatched"
]
}
}
# Setup husky
npx husky init
echo "npx lint-staged" > .husky/pre-commit
name: CI
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- run: npm ci
- run: npm run ci
# Runs: biome ci .
check:
stage: test
script:
- npm ci
- npm run ci
npm uninstall eslint prettier @typescript-eslint/parser @typescript-eslint/eslint-plugin
# Remove config files
rm .eslintrc.js .prettierrc .prettierignore .eslintignore
npm install --save-dev @biomejs/biome
npx @biomejs/biome init
Replace:
{
"scripts": {
"lint": "eslint .",
"format": "prettier --write ."
}
}
With:
{
"scripts": {
"check": "biome check --apply .",
"ci": "biome ci ."
}
}
{
"files": {
"ignore": [
"*.generated.ts",
"build/",
".sst/",
"coverage/"
]
}
}
{
"linter": {
"rules": {
"recommended": true,
"suspicious": {
"noExplicitAny": "error",
"noArrayIndexKey": "error"
}
}
}
}
{
"overrides": [
{
"include": ["**/*.test.ts", "**/*.spec.ts"],
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": "off"
},
"complexity": {
"noExcessiveCognitiveComplexity": "off"
}
}
}
}
]
}
# Ensures all committed code is formatted and linted
npx lint-staged
- run: npm run ci
Fail the build if code doesn't pass checks.
Configure your editor to format on save.
Start with defaults, only configure what you need:
{
"$schema": "https://biomejs.dev/schemas/1.5.3/schema.json",
"formatter": {
"lineWidth": 100
},
"linter": {
"rules": {
"recommended": true
}
}
}
Biome works great with TypeScript:
{
"javascript": {
"parser": {
"unsafeParameterDecoratorsEnabled": true
}
}
}
Biome is significantly faster than ESLint + Prettier:
# Formatting 5000 files
Prettier: ~30 seconds
Biome: ~1 second
# Linting 5000 files
ESLint: ~45 seconds
Biome: ~2 seconds
# Install locally
npm install --save-dev @biomejs/biome
# Or use npx
npx @biomejs/biome check .
Check your biome.json parser options:
{
"javascript": {
"parser": {
"unsafeParameterDecoratorsEnabled": true
}
}
}
Remove ESLint and Prettier:
npm uninstall eslint prettier
{
"extends": ["@company/biome-config"],
"formatter": {
"lineWidth": 120
}
}
{
"linter": {
"rules": {
"suspicious": {
"noExplicitAny": {
"level": "warn",
"fix": "none"
}
}
}
}
}
| Feature | Biome | ESLint + Prettier |
|---|---|---|
| Speed | 25x faster | Slower |
| Setup | Single tool | Two tools + config |
| Conflicts | None | Possible |
| Rules | Growing | Extensive |
| Plugins | Limited | Many |
| Memory | Lower | Higher |
ā Use Biome when:
ā ļø Consider alternatives when: