Skip to content

Instantly share code, notes, and snippets.

@RezaOwliaei
Last active November 4, 2025 04:37
Show Gist options
  • Save RezaOwliaei/948eed09f4232f3330747ea5e4cf607d to your computer and use it in GitHub Desktop.
Save RezaOwliaei/948eed09f4232f3330747ea5e4cf607d to your computer and use it in GitHub Desktop.
Biome Configurations
{
"$schema": "https://biomejs.dev/schemas/latest/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true,
"defaultBranch": "main"
},
"files": {
"includes": ["**/*.{js,mjs,ts,json,jsonc}"],
"maxSize": 1048576,
"ignoreUnknown": true
},
"formatter": {
"lineWidth": 80,
"indentStyle": "tab",
"indentWidth": 2,
"lineEnding": "lf"
},
"linter": {
"rules": {
"a11y": {
"recommended": true
},
"complexity": {
"noExtraBooleanCast": "error",
"noUselessCatch": "error"
},
"correctness": {
"noConstAssign": "error",
"noConstantCondition": "error",
"noEmptyCharacterClassInRegex": "error",
"noEmptyPattern": "error",
"noGlobalObjectCalls": "error",
"noInvalidConstructorSuper": "error",
"noNonoctalDecimalEscape": "error",
"noPrecisionLoss": "error",
"noSelfAssign": "error",
"noSetterReturn": "error",
"noSwitchDeclarations": "error",
"noUndeclaredVariables": "error",
"noUnreachable": "error",
"noUnreachableSuper": "error",
"noUnusedImports": "error",
"noUnusedFunctionParameters": "warn",
"noChildrenProp": "error",
"useIsNan": "error",
"useValidForDirection": "error",
"useYield": "error"
},
"performance": {
"noAccumulatingSpread": "warn",
"noDelete": "error"
},
"security": {
"noGlobalEval": "error"
},
"style": {
"noImplicitBoolean": "error",
"noNegationElse": "off",
"noParameterAssign": "warn",
"noRestrictedGlobals": "error",
"noShoutyConstants": "warn",
"noUnusedTemplateLiteral": "warn",
"useBlockStatements": "error",
"useCollapsedElseIf": "warn",
"useConst": "error",
"useDefaultParameterLast": "error",
"useExponentiationOperator": "error",
"useNumberNamespace": "error",
"useSingleVarDeclarator": "error",
"useTemplate": "warn",
"useConsistentArrayType": "error",
"useForOf": "error",
"useImportType": "error"
},
"suspicious": {
"noAssignInExpressions": "error",
"noAsyncPromiseExecutor": "error",
"noCatchAssign": "error",
"noClassAssign": "error",
"noCommentText": "error",
"noCompareNegZero": "error",
"noConsole": "warn",
"noControlCharactersInRegex": "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",
"noPrototypeBuiltins": "error",
"noRedeclare": "error",
"noShadowRestrictedNames": "error",
"noUnsafeDeclarationMerging": "error",
"noUnsafeNegation": "error",
"noFocusedTests": "error",
"noSkippedTests": "warn",
"useAdjacentOverloadSignatures": "error",
"useGetterReturn": "error"
},
"nursery": {
"useExplicitType": "warn",
"useNamingConvention": "warn"
}
}
},
"javascript": {
"globals": [
"console",
"process",
"Buffer",
"__dirname",
"__filename",
"Bun"
],
"formatter": {
"quoteStyle": "single",
"semicolons": "always",
"trailingCommas": "es5"
}
},
"json": {
"parser": {
"allowComments": true
}
},
"assist": {
"actions": {
"source": {
"organizeImports": "on"
}
}
},
"overrides": [
{
"includes": [
"*.test.{js,ts}",
"*.spec.{js,ts}",
"**/__tests__/**",
"**/test/**",
"**/tests/**"
],
"linter": {
"rules": {
"suspicious": {
"noConsole": "off"
},
"style": {
"noImplicitBoolean": "off"
}
}
}
},
{
"includes": [
"*.config.{js,ts,mjs}",
"*.setup.{js,ts}",
"vite.config.*",
"vitest.config.*",
"playwright.config.*"
],
"linter": {
"rules": {
"style": {
"noDefaultExport": "off"
},
"suspicious": {
"noConsole": "off"
}
}
}
},
{
"includes": ["package.json"],
"json": {
"parser": {
"allowComments": false
}
}
}
]
}

πŸš€ Complete Guide to Your Biome Configuration

πŸ“š What is Linting? (For Beginners)

Linting is like having a smart assistant that reads your code and helps you:

  • βœ… Find bugs before they cause problems
  • βœ… Follow best practices and coding standards
  • βœ… Keep code consistent across your project
  • βœ… Learn better coding patterns automatically

Think of it like spell-check for code - but much more powerful!

Biome is a modern, super-fast linter and formatter that helps you write better JavaScript and TypeScript code.


πŸ—οΈ Configuration Structure Overview

Your biome.json file is organized into these main sections:

πŸ“ biome.json
β”œβ”€β”€ πŸ”§ Basic Setup (schema, vcs, files)
β”œβ”€β”€ 🎨 Formatter (how code looks)
β”œβ”€β”€ πŸ›‘οΈ Linter Rules (what code quality rules to enforce)
β”œβ”€β”€ 🌐 JavaScript Settings (global variables)
β”œβ”€β”€ πŸ“„ JSON Settings (JSON parsing rules)
β”œβ”€β”€ πŸ€– Assist (automatic code improvements)
└── 🎯 Overrides (special rules for specific files)

πŸ”§ Basic Setup Section

Schema Declaration

"$schema": "https://biomejs.dev/schemas/latest/schema.json"

What it does: Enables autocomplete and validation in your code editor Beginner tip: Always keep this - it makes editing the config much easier!

Version Control Integration

"vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": true,
    "defaultBranch": "main"
}

What it does:

  • enabled: Turns on git integration
  • clientKind: Tells Biome you're using git
  • useIgnoreFile: Respects your .gitignore file (won't check ignored files)
  • defaultBranch: Your main git branch name

Why it matters: Biome will automatically ignore files in your .gitignore, making it faster and more relevant

File Targeting

"files": {
    "includes": ["**/*.{js,mjs,ts,json,jsonc}"],
    "maxSize": 1048576,
    "ignoreUnknown": true
}

What it does:

  • includes: Only check these file types (JavaScript, TypeScript, JSON)
  • maxSize: Skip files larger than 1MB (prevents slowdowns)
  • ignoreUnknown: Don't show warnings for file types Biome doesn't understand

Beginner tip: The **/* pattern means "look in all folders and subfolders"


🎨 Formatter Section

"formatter": {
    "lineWidth": 80,
    "indentStyle": "tab",
    "indentWidth": 2,
    "lineEnding": "lf"
}

What it does:

  • lineWidth: Maximum 80 characters per line (classic standard)
  • indentStyle: Use tabs for indentation (better for accessibility)
  • indentWidth: 2 spaces worth of indentation
  • lineEnding: Unix-style line endings (LF) for cross-platform consistency

Why these choices?:

  • 80 characters: Works on all screen sizes, forces concise code
  • Tabs: Users can set their preferred width in their editor
  • LF endings: Prevents git issues between Windows/Mac/Linux

πŸ›‘οΈ Linter Rules (The Heart of Your Config)

Your linter rules are organized into categories. Here's what each category does:

🌐 Accessibility Rules (NEW!)

Purpose: Make your web apps usable by everyone, including people with disabilities

"a11y": {
    "recommended": true    // Enable all recommended accessibility rules
}

What it catches: Missing alt text, improper ARIA usage, keyboard navigation issues Why important: Makes your apps inclusive and often legally required

🧩 Complexity Rules

Purpose: Prevent overly complex code that's hard to understand

"complexity": {
    "noExtraBooleanCast": "error",    // Don't use Boolean(x) when !!x works
    "noUselessCatch": "error"         // Don't catch errors just to rethrow them
}

Example of what gets caught:

// ❌ Bad - extra boolean cast
if (Boolean(someValue)) { }

// βœ… Good - direct boolean check
if (someValue) { }

βœ… Correctness Rules

Purpose: Catch actual bugs and programming errors

Key rules explained:

  • noConstAssign: Can't reassign const variables
  • noUndeclaredVariables: Must declare variables before using
  • noUnreachable: Code after return statements is unreachable
  • noUnusedImports: Remove imports you're not using (NEW!)
  • noUnusedFunctionParameters: Warn about unused function parameters (NEW!)
  • noChildrenProp: Prevent React children prop misuse (NEW!)
  • useIsNan: Use Number.isNaN() instead of x === NaN

Example:

// ❌ This will error - can't reassign const
const name = "John";
name = "Jane"; // ERROR!

// βœ… Good - use let for reassignable variables
let name = "John";
name = "Jane"; // OK!

⚑ Performance Rules

Purpose: Prevent code that runs slowly

"performance": {
    "noAccumulatingSpread": "warn",   // Don't use spread in loops
    "noDelete": "error"               // Don't use delete operator
}

Example:

// ❌ Bad - slow spreading in loop
let result = [];
for (let item of items) {
    result = [...result, item]; // Gets slower with each iteration!
}

// βœ… Good - use push instead
let result = [];
for (let item of items) {
    result.push(item); // Fast!
}

πŸ”’ Security Rules

Purpose: Prevent security vulnerabilities

"security": {
    "noGlobalEval": "error"           // Never use eval() - it's dangerous!
}

🎨 Style Rules

Purpose: Keep code consistent and readable

Important ones:

  • useConst: Use const when values don't change
  • useTemplate: Use template literals instead of string concatenation
  • useConsistentArrayType: Use string[] instead of Array<string>
  • useForOf: Use modern for...of loops instead of traditional for loops (NEW!)
  • useImportType: Use TypeScript type-only imports when possible (NEW!)

Examples:

// ❌ Style issues
let name = "John";  // Should be const
let msg = "Hello " + name;  // Should use template
let items: Array<string> = [];  // Inconsistent array type

// βœ… Good style
const name = "John";
const msg = `Hello ${name}`;
const items: string[] = [];

πŸ•΅οΈ Suspicious Rules

Purpose: Catch code that looks wrong or dangerous

Key highlights:

  • noConsole: Warns about console.log (should be removed in production)
  • noDebugger: No debugger statements in production
  • noDoubleEquals: Use === instead of ==
  • noExplicitAny: Avoid TypeScript's any type
  • noFocusedTests: Prevent .only() in test files (NEW!)
  • noSkippedTests: Warn about .skip() in test files (NEW!)

Examples:

// ❌ Suspicious patterns
if (x == y) { }          // Should be ===
let data: any = {};      // Should have proper type
console.log("debug");    // Should be removed before production

// βœ… Better patterns
if (x === y) { }
let data: User = {};
// Use proper logging library instead

🌱 Nursery Rules

Purpose: Newest experimental rules (cutting-edge best practices)

"nursery": {
    "useExplicitType": "warn",        // Encourage explicit return types
    "useNamingConvention": "warn"     // Enforce naming standards
}

🌐 JavaScript Configuration

"javascript": {
    "globals": ["console", "process", "Buffer", "__dirname", "__filename", "Bun"],
    "formatter": {
        "quoteStyle": "single",
        "semicolons": "always", 
        "trailingCommas": "es5"
    }
}

Global Variables:

  • Tells Biome these global variables are OK to use
  • Prevents "undefined variable" errors for runtime-specific globals
  • Your globals: Node.js + Bun runtime variables

JavaScript Formatter (NEW!):

  • quoteStyle: Use single quotes instead of double quotes
  • semicolons: Always use semicolons (safer than omitting)
  • trailingCommas: Add trailing commas for ES5 compatibility (better git diffs)

πŸ“„ JSON Configuration

"json": {
    "parser": {
        "allowComments": true    // Allow // comments in JSON files
    }
}

What it does: Allows comments in JSON files (normally not allowed) Useful for: Configuration files that benefit from explanations


πŸ€– Assist (Auto-improvements)

"assist": {
    "actions": {
        "source": {
            "organizeImports": "on"    // Auto-sort import statements
        }
    }
}

What it does: Automatically organizes your import statements Example: Sorts imports alphabetically and groups them logically

Before:

import { useState } from 'react';
import axios from 'axios';
import { Button } from './Button';
import React from 'react';

After auto-organize:

import React, { useState } from 'react';
import axios from 'axios';
import { Button } from './Button';

🎯 Overrides (Context-Specific Rules)

Your config has smart overrides for different types of files:

πŸ§ͺ Test Files Override

{
    "includes": ["*.test.{js,ts}", "*.spec.{js,ts}", "**/__tests__/**"],
    "linter": {
        "rules": {
            "suspicious": { "noConsole": "off" },      // console.log OK in tests
            "style": { "noImplicitBoolean": "off" }    // Relaxed boolean rules
        }
    }
}

Why: Test files often need console.log for debugging and have different patterns

βš™οΈ Config Files Override

{
    "includes": ["*.config.{js,ts,mjs}", "vite.config.*"],
    "linter": {
        "rules": {
            "style": { "noDefaultExport": "off" },     // Config files often need default exports
            "suspicious": { "noConsole": "off" }       // Console OK for build logs
        }
    }
}

Why: Configuration files often need default exports and logging

πŸ“¦ Package.json Override

{
    "includes": ["package.json"],
    "json": {
        "parser": { "allowComments": false }    // package.json can't have comments
    }
}

Why: Real package.json files don't support comments (npm requirement)


🚦 Understanding Severity Levels

Your config uses three severity levels:

Level What it means Example
"error" ❌ Must fix - blocks builds Syntax errors, bugs
"warn" ⚠️ Should fix - doesn't block Style issues, code smells
"off" πŸ”‡ Ignored - rule disabled Allowed in specific contexts

πŸ› οΈ How to Use Your Configuration

Basic Commands (from your package.json):

# Check and fix all issues
bun run check

# Only check formatting
bun run format:check

# Only check linting
bun run lint:check

# Run in CI/CD (no changes, just report)
bun run check:ci

Understanding Output:

index.ts:1:1 lint/suspicious/noConsole  FIXABLE  ━━━━━━━━━━━
  ⚠ Don't use console.
  > 1 β”‚ console.log("Hello via Bun!");
      β”‚ ^^^^^^^^^^^

Reading this:

  • index.ts:1:1 = File name, line 1, column 1
  • lint/suspicious/noConsole = Rule category/name
  • FIXABLE = Biome can auto-fix this
  • ⚠ = Warning level (not an error)

πŸŽ“ Best Practices for Beginners

1. Start Gradually

  • Begin with warnings, make them errors later
  • Focus on one rule category at a time

2. Understand Before Disabling

  • Don't just turn off rules that seem annoying
  • Learn why the rule exists first

3. Use Auto-fix

  • Let Biome fix what it can automatically
  • Review the changes to learn patterns

4. Configure Your Editor

  • Install Biome extension for VS Code/your editor
  • Enable format-on-save for automatic formatting

5. Team Consistency

  • Share this config with your team
  • Use the same rules across all projects

πŸ”§ Customizing Your Config

To add a new rule:

"style": {
    "existingRule": "error",
    "newRule": "warn"    // Add here
}

To disable a rule:

"suspicious": {
    "annoying-rule": "off"    // Disable completely
}

To change severity:

"correctness": {
    "someRule": "warn"    // Change from "error" to "warn"
}

πŸš€ Advanced Tips

  1. Performance: Your config is optimized for speed with maxSize limits
  2. Modern Features: Nursery rules give you cutting-edge best practices
  3. Context-Aware: Overrides make rules smart about file types
  4. Minimal: No redundant default values = faster parsing

πŸ“– Learning Resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment