.agents/skills/eslint-biome/SKILL.md
ESLint 9 flat config and Biome linter configuration. Covers typescript-eslint, rule categories, migration from legacy config, and performance optimization. USE WHEN: user mentions "ESLint 9", "Biome", "flat config", "eslint.config.mjs", asks about "typescript-eslint", "migration to ESLint 9", "linter performance", "Biome vs ESLint" DO NOT USE FOR: legacy ESLint - use `eslint` skill, Java/Spring - use SonarQube, basic linting concepts - use `quality-common`
npx skillsauth add d-subrahmanyam/deno-fresh-microservices eslint-biomeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
eslint skill for old config formattypescript-eslint skill for deep TypeScript lintingsonarqube skillquality-common for SOLID/Clean CodeDeep Knowledge: Use
mcp__documentation__fetch_docswith technology:eslintorbiomefor comprehensive documentation.
| Tool | Documentation | |------|---------------| | ESLint 9 | https://eslint.org/docs/latest/ | | typescript-eslint | https://typescript-eslint.io/ | | Biome | https://biomejs.dev/ | | ESLint Rules | https://eslint.org/docs/latest/rules/ | | Biome Rules | https://biomejs.dev/linter/rules/ |
npm install --save-dev eslint @eslint/js typescript typescript-eslint
// eslint.config.mjs
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
);
// eslint.config.mjs
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
);
// eslint.config.mjs
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import reactPlugin from 'eslint-plugin-react';
import reactHooksPlugin from 'eslint-plugin-react-hooks';
export default tseslint.config(
// Ignores
{
ignores: ['dist/**', 'node_modules/**', '*.config.js'],
},
// Base configs
eslint.configs.recommended,
...tseslint.configs.strictTypeChecked,
...tseslint.configs.stylisticTypeChecked,
// TypeScript files
{
files: ['**/*.ts', '**/*.tsx'],
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
// Prevent bugs
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/await-thenable': 'error',
// Code quality
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/explicit-function-return-type': 'warn',
'@typescript-eslint/consistent-type-imports': 'error',
// Complexity
'complexity': ['warn', 10],
'max-depth': ['warn', 4],
'max-lines-per-function': ['warn', 50],
},
},
// React files
{
files: ['**/*.tsx'],
plugins: {
react: reactPlugin,
'react-hooks': reactHooksPlugin,
},
rules: {
...reactPlugin.configs.recommended.rules,
...reactHooksPlugin.configs.recommended.rules,
'react/react-in-jsx-scope': 'off',
},
settings: {
react: { version: 'detect' },
},
},
// Test files
{
files: ['**/*.test.ts', '**/*.test.tsx', '**/*.spec.ts'],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'max-lines-per-function': 'off',
},
},
);
| Preset | Description |
|--------|-------------|
| recommended | Core rules without type checking |
| recommendedTypeChecked | Recommended + type-aware rules |
| strict | All recommended + stricter rules |
| strictTypeChecked | Strict + type-aware rules |
| stylistic | Style/convention rules |
| stylisticTypeChecked | Stylistic + type-aware |
rules: {
// Async/Promise safety
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/require-await': 'error',
// Type safety
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-unsafe-call': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-return': 'error',
// Best practices
'@typescript-eslint/no-unnecessary-condition': 'error',
'@typescript-eslint/prefer-nullish-coalescing': 'error',
'@typescript-eslint/prefer-optional-chain': 'error',
}
npm install --save-dev @biomejs/biome
npx @biomejs/biome init
{
"$schema": "https://biomejs.dev/schemas/1.9.0/schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"complexity": {
"noExcessiveCognitiveComplexity": {
"level": "warn",
"options": { "maxAllowedComplexity": 15 }
}
},
"correctness": {
"noUnusedImports": "error",
"noUnusedVariables": "error",
"useExhaustiveDependencies": "warn"
},
"suspicious": {
"noExplicitAny": "error",
"noConsoleLog": "warn"
},
"style": {
"useConst": "error",
"noNonNullAssertion": "warn"
},
"security": {
"noDangerouslySetInnerHtml": "error"
}
}
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"semicolons": "always"
}
}
}
| Category | Rules | Description | |----------|-------|-------------| | a11y | 40+ | Accessibility problems | | complexity | 15+ | Code simplification | | correctness | 60+ | Guaranteed errors | | performance | 10+ | Efficiency improvements | | security | 5+ | Security flaws | | style | 50+ | Consistent code style | | suspicious | 50+ | Likely incorrect patterns | | nursery | 100+ | Experimental rules |
# Check all
npx biome check .
# Fix auto-fixable issues
npx biome check --write .
# Lint only
npx biome lint .
# Format only
npx biome format --write .
# CI mode (no writes)
npx biome ci .
# Automatic migration
npx @biomejs/biome migrate eslint --write
# With inspired rules
npx @biomejs/biome migrate eslint --include-inspired --write
# Migrate prettier config too
npx @biomejs/biome migrate prettier --write
| Plugin | Biome Support | |--------|---------------| | @typescript-eslint | Full | | eslint-plugin-react | Full | | eslint-plugin-react-hooks | Full | | eslint-plugin-jsx-a11y | Full | | eslint-plugin-unicorn | Partial | | eslint-plugin-import | Partial |
| ESLint | Biome |
|--------|-------|
| no-unused-vars | noUnusedVariables |
| no-console | noConsoleLog |
| prefer-const | useConst |
| @typescript-eslint/no-explicit-any | noExplicitAny |
| Feature | ESLint 9 | Biome | |---------|----------|-------| | Speed | ~3-5s/10k lines | ~200ms/10k lines | | Config | JavaScript | JSON/JSONC | | Plugins | 1000+ | Built-in only | | Formatter | Needs Prettier | Built-in | | Type-aware | Full support | ~85% coverage | | Languages | JS/TS + plugins | JS/TS/JSON/CSS |
- name: Lint
run: npx eslint . --max-warnings=0
# With caching
- name: Lint with cache
run: npx eslint . --cache --cache-location node_modules/.cache/eslint
- name: Setup Biome
uses: biomejs/setup-biome@v2
with:
version: latest
- name: Run Biome
run: biome ci .
| Metric | Target | |--------|--------| | Lint warnings | 0 | | Lint errors | 0 | | Type coverage | > 95% | | Lint time (CI) | < 30s |
| Anti-Pattern | Why It's Bad | Correct Approach |
|--------------|--------------|------------------|
| Using ESLint without type checking | Misses 50% of TS issues | Use recommendedTypeChecked |
| Biome + ESLint both linting same files | Duplicate work, conflicts | Choose one per file type |
| No ignores in flat config | Lints dist/, node_modules/ | Add ignores at top of config |
| Type checking all JS files | Slow, JS has no types | Limit to **/*.ts files only |
| Not using Biome CI mode | Different results locally vs CI | Use biome ci . in pipelines |
| Mixing .eslintrc and flat config | Confusing, deprecated pattern | Migrate fully to flat config |
| Issue | Likely Cause | Solution |
|-------|--------------|----------|
| ESLint not finding types | projectService not enabled | Add projectService: true to parserOptions |
| Biome migration creates 1000+ errors | Stricter rules than ESLint | Use --write to auto-fix, adjust rules |
| Linting takes 2+ minutes | Type checking entire codebase | Use files: ['**/*.ts'] for type rules |
| Biome doesn't support plugin X | Limited plugin ecosystem | Stick with ESLint or find alternative |
| Flat config not recognized | Wrong file name | Must be eslint.config.mjs (not .js) |
| Rules overriding each other | Order in config array | Later configs override earlier ones |
development
Guidelines for building high-performance APIs with Fastify and TypeScript, covering validation, Prisma integration, and testing best practices
development
FastAPI modern Python web framework. Covers routing, Pydantic models, dependency injection, and async support. Use when building Python APIs. USE WHEN: user mentions "fastapi", "pydantic", "async python api", "python rest api", asks about "dependency injection python", "python openapi", "python swagger", "async endpoints", "python api validation", "fastapi middleware" DO NOT USE FOR: Django apps - use `django` instead, Flask apps - use `flask` instead, synchronous Python APIs without type hints, GraphQL-only APIs
tools
FastAPI integration testing specialist. Covers synchronous TestClient, async httpx AsyncClient, dependency injection overrides, auth testing (JWT, OAuth2, API keys), WebSocket testing, file uploads, background tasks, middleware testing, and HTTP mocking with respx, responses, and pytest-httpserver. USE WHEN: user mentions "FastAPI test", "TestClient", "httpx async test", "dependency override test", "respx mock", asks about testing FastAPI endpoints, authentication in tests, or HTTP client mocking. DO NOT USE FOR: Django - use `pytest-django`; pytest internals - use `pytest`; Container infrastructure - use `testcontainers-python`
development
Expert in FastAPI Python development with best practices for APIs and async operations