From britenites
ESLint, Prettier, Ruff, mypy, and TypeScript strict mode configuration patterns. Use when setting up linting, formatting, or code quality tooling for a new project, reviewing existing configs, generating config files, or adding lint steps to CI. Triggers on tasks involving ESLint, Prettier, Ruff, mypy, Black, code style, linting, formatting, or code quality enforcement.
npx claudepluginhub brite-nites/britenites-claude-pluginsThis skill uses the workspace's default tool permissions.
Canonical configuration patterns for JavaScript/TypeScript and Python code quality tooling. Auto-detect project type, generate config files, and integrate with CI.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Canonical configuration patterns for JavaScript/TypeScript and Python code quality tooling. Auto-detect project type, generate config files, and integrate with CI.
Identify the project stack from these markers before generating configs:
| Marker file | Stack | Tools to configure |
|---|---|---|
package.json | JavaScript/TypeScript | ESLint, Prettier |
tsconfig.json | TypeScript (additional) | TypeScript strict mode, tsc --noEmit |
pyproject.toml | Python | Ruff, mypy |
setup.py or setup.cfg | Python (legacy) | Ruff, mypy |
Both package.json + pyproject.toml | Full-stack | All of the above |
When auto-detecting, check for existing configs first (.eslintrc*, eslint.config.*, .prettierrc*, [tool.ruff] in pyproject.toml) — upgrade rather than overwrite.
Use eslint.config.mjs (flat config). Legacy .eslintrc.* is deprecated as of ESLint v9.
// eslint.config.mjs
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import prettierConfig from "eslint-config-prettier";
export default tseslint.config(
js.configs.recommended,
tseslint.configs.strictTypeChecked,
tseslint.configs.stylisticTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
{
rules: {
"@typescript-eslint/no-unused-vars": [
"error",
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
],
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-import-type-side-effects": "error",
},
},
prettierConfig,
{
ignores: ["node_modules/", "dist/", ".next/", "coverage/"],
},
);
For JS-only projects (no TypeScript), drop tseslint and use:
// eslint.config.mjs
import js from "@eslint/js";
export default [
js.configs.recommended,
{
rules: {
"no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
},
},
{ ignores: ["node_modules/", "dist/"] },
];
Next.js projects — use eslint-config-next with FlatCompat (the Next.js config still uses legacy format internally):
// eslint.config.mjs
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import prettierConfig from "eslint-config-prettier";
import { FlatCompat } from "@eslint/eslintrc";
import path from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const compat = new FlatCompat({ baseDirectory: __dirname });
export default tseslint.config(
js.configs.recommended,
tseslint.configs.strictTypeChecked,
...compat.extends("next/core-web-vitals"),
// ... rules, prettierConfig, ignores
);
Install: npm install -D eslint @eslint/js typescript-eslint eslint-config-prettier prettier eslint-config-next @eslint/eslintrc
{
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 100,
"bracketSpacing": true,
"arrowParens": "always"
}
.prettierignore (uses .gitignore syntax):
node_modules/
dist/
.next/
coverage/
pnpm-lock.yaml
To avoid ESLint/Prettier conflicts, install eslint-config-prettier and add it as the last config entry before ignores (see the ESLint template above where prettierConfig is already included).
Key tsconfig.json strict settings — enable all of these:
{
"compilerOptions": {
"strict": true, // Enables all strict flags below
"noUncheckedIndexedAccess": true, // Array/object index returns T | undefined
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"forceConsistentCasingInFileNames": true,
"exactOptionalPropertyTypes": true
}
}
strict: true enables: strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitAny, noImplicitThis, alwaysStrict, useUnknownInCatchVariables.
Ruff replaces flake8, isort, Black, pyupgrade, and more. Single tool for both linting and formatting.
# pyproject.toml
[tool.ruff]
target-version = "py312"
line-length = 120
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
"SIM", # flake8-simplify
"TCH", # flake8-type-checking
"RUF", # ruff-specific rules
]
ignore = [
"E501", # line length (handled by formatter)
]
[tool.ruff.lint.isort]
known-first-party = ["your_package"] # REPLACE with your actual package name
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
Commands: ruff check --fix . (lint), ruff format . (format).
Migration from Black/flake8/isort: Ruff is a drop-in replacement. Remove legacy configs (.flake8, .isort.cfg, pyproject.toml [tool.black]) and consolidate into [tool.ruff].
# pyproject.toml
[tool.mypy]
python_version = "3.12"
strict = true # enables disallow_untyped_defs, no_implicit_optional, warn_return_any, etc.
warn_unused_ignores = true # included in strict since mypy 1.0 — explicit here for clarity
For incremental adoption on existing codebases, start with per-module overrides:
[tool.mypy]
python_version = "3.12"
warn_return_any = true
[[tool.mypy.overrides]]
module = "your_package.core.*"
strict = true
[[tool.mypy.overrides]]
module = "your_package.legacy.*"
ignore_errors = true
Prefer Ruff for new projects. Black is only needed for teams already using it. Ruff's formatter is Black-compatible.
# pyproject.toml (if still using Black)
[tool.black]
line-length = 120
target-version = ["py312"]
Pin actions to commit SHAs to prevent supply chain attacks. Add permissions: contents: read for least privilege.
# .github/workflows/lint.yml
name: Lint
on: [push, pull_request]
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: ".nvmrc" # or node-version: "22"
cache: "npm"
- run: npm ci
- run: npx --no-install eslint --max-warnings 0 .
- run: npx --no-install prettier --check .
- run: if [ -f tsconfig.json ]; then npx --no-install tsc --noEmit; fi
# .github/workflows/lint.yml
name: Lint
on: [push, pull_request]
permissions:
contents: read
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2f # v5.3.0
with:
python-version: "3.12"
cache: "pip"
- run: pip install -r requirements-dev.txt # ruff, mypy pinned
- run: ruff check .
- run: ruff format --check .
- run: mypy --ignore-missing-imports . # remove flag once type stubs are installed
name: Code Quality
on: [push, pull_request]
permissions:
contents: read
jobs:
lint-js:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: ".nvmrc"
cache: "npm"
- run: npm ci
- run: npx --no-install eslint --max-warnings 0 .
- run: npx --no-install prettier --check .
- run: if [ -f tsconfig.json ]; then npx --no-install tsc --noEmit; fi
lint-python:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2f # v5.3.0
with:
python-version: "3.12"
cache: "pip"
- run: pip install -r requirements-dev.txt
- run: ruff check .
- run: ruff format --check .
- run: mypy --ignore-missing-imports .
When generating configs for a project, follow this order:
known-first-party, ignores, and project-specific rules"lint": "eslint .", "format": "prettier --write ."JS/TS (npm):
npm install -D eslint @eslint/js typescript-eslint eslint-config-prettier prettier # versions pinned in package.json
Python (pip/uv):
pip install ruff mypy # pin in requirements-dev.txt: ruff==0.11.x mypy==1.15.x