Claude
Skills
Sign in
Back

linter-formatter-init

Included with Lifetime
$97 forever

Set up Biome (default) or ESLint + Prettier, Vitest testing, and pre-commit hooks for any JavaScript/TypeScript project. Uses Bun as the package manager. Use this skill when initializing code quality tooling for a new project or adding linting to an existing one.

Generalscriptsassets

What this skill does


# Linter Formatter Init

Set up comprehensive linting, formatting, and testing for JavaScript/TypeScript projects using **Biome 2.3+** (default), **Vitest**, and **Bun**.

**IMPORTANT**: Always uses Biome 2.3+ (latest) - never older versions.

## Purpose

This skill automates the setup of:

- **Biome** for linting + formatting (default, recommended)
- **Vitest** for testing with coverage (use `--vitest` flag)
- ESLint + Prettier (legacy, use `--eslint` flag)
- Husky + lint-staged for pre-commit hooks
- VS Code/Cursor settings for auto-format on save
- bun scripts for manual linting, formatting, and testing

## When to Use

Use this skill when:

- Starting a new JS/TS project
- Adding linting to an existing project without tooling
- Standardizing code quality across a team
- Setting up pre-commit hooks to enforce quality

## Quick Start

```bash
# Default setup (Biome) - RECOMMENDED
python3 scripts/setup.py \
  --root /path/to/project

# Use ESLint + Prettier instead (legacy)
python3 scripts/setup.py \
  --root /path/to/project \
  --eslint

# ESLint + Prettier with TypeScript
python3 scripts/setup.py \
  --root /path/to/project \
  --eslint \
  --typescript

# Skip pre-commit hooks
python3 scripts/setup.py \
  --root /path/to/project \
  --no-hooks

# Add Vitest testing with 80% coverage threshold
python3 scripts/setup.py \
  --root /path/to/project \
  --vitest

# Full setup: Biome + Vitest + Husky
python3 scripts/setup.py \
  --root /path/to/project \
  --vitest \
  --coverage 80
```

## What Gets Installed

### Dependencies

**Biome 2.3+ (default):**

- @biomejs/biome@latest (always latest, minimum 2.3+)

**Vitest (with --vitest):**

- vitest
- @vitest/coverage-v8

**ESLint + Prettier (legacy, with --eslint):**

- eslint
- prettier
- eslint-config-prettier
- eslint-plugin-prettier
- @typescript-eslint/parser (if --typescript)
- @typescript-eslint/eslint-plugin (if --typescript)

**Pre-commit hooks:**

- husky
- lint-staged

### Configuration Files (Biome - Default)

```
project/
├── biome.json              # Biome config (lint + format)
├── .vscode/
│   └── settings.json       # Auto-format on save
├── .husky/
│   └── pre-commit          # Pre-commit hook
└── package.json            # Updated with scripts + lint-staged
```

### Configuration Files (ESLint + Prettier - Legacy)

```
project/
├── .eslintrc.json          # ESLint config
├── .prettierrc             # Prettier config
├── .prettierignore         # Prettier ignore patterns
├── .eslintignore           # ESLint ignore patterns
├── .vscode/
│   └── settings.json       # Auto-format on save
├── .husky/
│   └── pre-commit          # Pre-commit hook
└── package.json            # Updated with scripts + lint-staged
```

### Bun Scripts Added (Biome)

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

### Bun Scripts Added (Vitest)

```json
{
  "scripts": {
    "test": "vitest run",
    "test:watch": "vitest",
    "test:coverage": "vitest run --coverage",
    "test:ui": "vitest --ui"
  }
}
```

### Bun Scripts Added (ESLint + Prettier)

```json
{
  "scripts": {
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
    "lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
    "format": "prettier --write .",
    "format:check": "prettier --check ."
  }
}
```

## Biome Configuration (Default)

Biome is a fast, all-in-one linter and formatter. The default config includes:

```json
{
  "$schema": "https://biomejs.dev/schemas/2.3.12/schema.json",
  "assist": {
    "actions": {
      "source": { "organizeImports": "on" }
    }
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "complexity": { "noForEach": "off" },
      "style": { "noNonNullAssertion": "off" },
      "suspicious": { "noArrayIndexKey": "off", "noExplicitAny": "warn" }
    }
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "single",
      "trailingCommas": "es5",
      "semicolons": "always"
    }
  }
}
```

### Customization

After setup, customize `biome.json` to adjust:

- Linting rules
- Formatting preferences
- File ignore patterns

## Vitest Configuration (with --vitest)

When you use the `--vitest` flag, this skill creates a `vitest.config.ts`:

```typescript
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    globals: true,
    environment: "node", // or "jsdom" for frontend
    include: ["src/**/*.{test,spec}.{ts,tsx}", "**/*.{test,spec}.{ts,tsx}"],
    exclude: ["node_modules", "dist", ".next", "build"],
    coverage: {
      provider: "v8",
      reporter: ["text", "json", "html", "lcov"],
      include: ["src/**/*.ts", "src/**/*.tsx"],
      exclude: ["src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"],
      thresholds: {
        lines: 80,
        functions: 80,
        branches: 75,
        statements: 80,
      },
    },
    mockReset: true,
    restoreMocks: true,
  },
});
```

### Coverage Thresholds

Default threshold is 80%. Customize with:

```bash
python3 scripts/setup.py \
  --root /path/to/project \
  --vitest \
  --coverage 90  # Set to 90%
```

### Test Setup File

Creates `src/test/setup.ts` for global test configuration:

```typescript
import { expect, afterEach } from "vitest";
import { cleanup } from "@testing-library/react"; // For React projects

// Cleanup after each test
afterEach(() => {
  cleanup();
});
```

## Pre-commit Hooks

When enabled (default), lint-staged runs on every commit:

**Biome (default):**

```json
{
  "lint-staged": {
    "*.{js,jsx,ts,tsx,json,css}": ["bunx biome check --write"]
  }
}
```

**ESLint + Prettier (legacy):**

```json
{
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{json,md,yml,yaml}": ["prettier --write"]
  }
}
```

This ensures:

- All committed code passes linting
- All committed code is formatted
- No broken code enters the repo

## VS Code / Cursor Integration

The skill creates `.vscode/settings.json`:

**Biome (default):**

```json
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "biomejs.biome",
  "editor.codeActionsOnSave": {
    "source.organizeImports.biome": "explicit",
    "quickfix.biome": "explicit"
  },
  "[typescript]": {
    "editor.defaultFormatter": "biomejs.biome"
  }
}
```

**ESLint + Prettier (legacy):**

```json
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  }
}
```

## Why Biome Over ESLint + Prettier?

- **Faster**: Written in Rust, 10-100x faster than ESLint + Prettier
- **Simpler**: One tool instead of two, one config file
- **No conflicts**: No need for eslint-config-prettier or similar workarounds
- **Better defaults**: Sensible rules out of the box

## Monorepo Support

For monorepos, run from the root:

```bash
python3 scripts/setup.py \
  --root /path/to/monorepo \
  --monorepo
```

This adds root-level config that applies to all packages.

## Troubleshooting

### Pre-commit hooks not running

```bash
# Reinstall husky
bunx husky
chmod +x .husky/pre-commit
```

### Format on save not working (Biome)

1. Install the Biome extension in VS Code/Cursor
2. Set Biome as default formatter
3. Enable "Format on Save" in settings

### Format on save not working (ESLint + Prettier)

1. Install the Prettier extension in VS Code/Cursor
2. Set Prettier as default formatter
3. Enable "Format on Save" in settings

## Framework-Specific Configs (ESLint mode only)

When using `--eslint`, the skill detects common frameworks and adjusts config:

- **Next.js**: Adds `next/core-web-vitals` to ESLint
- **React**: Adds `eslint-plugin-react` and `eslint-plugin-react-hooks`
- **NestJS**: Adds rules f

Related in General