Use when adding new error messages to React, or seeing "unknown error code" warnings.
npx skills add shipshitdev/library --skill "linter-formatter-init"
Install specific skill from multi-skill repository
# Description
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.
# SKILL.md
name: linter-formatter-init
description: 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.
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
--vitestflag) - ESLint + Prettier (legacy, use
--eslintflag) - 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
# Default setup (Biome) - RECOMMENDED
python3 ~/.claude/skills/linter-formatter-init/scripts/setup.py \
--root /path/to/project
# Use ESLint + Prettier instead (legacy)
python3 ~/.claude/skills/linter-formatter-init/scripts/setup.py \
--root /path/to/project \
--eslint
# ESLint + Prettier with TypeScript
python3 ~/.claude/skills/linter-formatter-init/scripts/setup.py \
--root /path/to/project \
--eslint \
--typescript
# Skip pre-commit hooks
python3 ~/.claude/skills/linter-formatter-init/scripts/setup.py \
--root /path/to/project \
--no-hooks
# Add Vitest testing with 80% coverage threshold
python3 ~/.claude/skills/linter-formatter-init/scripts/setup.py \
--root /path/to/project \
--vitest
# Full setup: Biome + Vitest + Husky
python3 ~/.claude/skills/linter-formatter-init/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)
{
"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)
{
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"test:ui": "vitest --ui"
}
}
Bun Scripts Added (ESLint + Prettier)
{
"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:
{
"$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:
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:
python3 ~/.claude/skills/linter-formatter-init/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:
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):
{
"lint-staged": {
"*.{js,jsx,ts,tsx,json,css}": ["bunx biome check --write"]
}
}
ESLint + Prettier (legacy):
{
"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):
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "biomejs.biome",
"editor.codeActionsOnSave": {
"source.organizeImports.biome": "explicit",
"quickfix.biome": "explicit"
},
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
}
}
ESLint + Prettier (legacy):
{
"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:
python3 ~/.claude/skills/linter-formatter-init/scripts/setup.py \
--root /path/to/monorepo \
--monorepo
This adds root-level config that applies to all packages.
Troubleshooting
Pre-commit hooks not running
# Reinstall husky
bunx husky
chmod +x .husky/pre-commit
Format on save not working (Biome)
- Install the Biome extension in VS Code/Cursor
- Set Biome as default formatter
- Enable "Format on Save" in settings
Format on save not working (ESLint + Prettier)
- Install the Prettier extension in VS Code/Cursor
- Set Prettier as default formatter
- 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-vitalsto ESLint - React: Adds
eslint-plugin-reactandeslint-plugin-react-hooks - NestJS: Adds rules for decorators and DI patterns
Manual Setup (Alternative)
If you prefer manual setup over the script:
Biome:
bun add -D @biomejs/biome husky lint-staged
bunx biome init
bunx husky
ESLint + Prettier:
bun add -D eslint prettier eslint-config-prettier eslint-plugin-prettier husky lint-staged
bun add -D @typescript-eslint/parser @typescript-eslint/eslint-plugin
bunx eslint --init
bunx husky
Then copy configs from ~/.claude/skills/linter-formatter-init/assets/configs/
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.