Lint Sync
Purpose
Two workflows in one skill:
- Migrate — Move ESLint/Prettier rules to Biome or Oxc with rule-by-rule comparison
- Modernize — Update existing Biome/Oxc configs: promote nursery rules, enable new quality flags, apply latest formatter options
When to Use This Skill
Trigger phrases: "lint sync", "lint-sync", "eslint biome overlap", "biome migration", "oxlint migration", "migrate to oxc", "disable eslint rules", "modernize biome config", "update biome rules", "promote nursery rules", "update oxlint config"
Modes
| Mode | Trigger | Description |
|---|
| sync | No mode or | Quick overlap check (migrate) or nursery/feature check (modernize). |
| audit | | Full analysis with performance data, coverage stats, migration/modernization checklist. |
| update | | Refresh mapping and version reference files from upstream sources. |
Documentation
Before fetching docs from the web, check
for Context7 library IDs and direct URLs. This saves tokens significantly.
Context7 IDs for quick lookups:
- Biome: (5357 snippets)
- Oxc: (5057 snippets)
- Vite+: (210 snippets)
Asking the User
Every question in this skill is written as
options. Use that tool where
the host offers it, or the host's nearest structured-choice equivalent. Where the host has
neither, ask the same question in normal chat as a numbered list of 2–5 options —
recommended first, one short line of description each — and wait for the user to reply
with a number.
Workflow
Step 1: Detect All Configs
Find all relevant configuration files:
bash
# Source tools (ESLint / Prettier)
fd -t f '(eslint\.config\.(js|ts|mjs|cjs)|\.eslintrc\..*)' --max-depth 2
fd -t f '(\.prettierrc(\.(js|cjs|mjs|json|yaml|yml|toml))?|prettier\.config\.(js|cjs|mjs|ts))' --max-depth 2
# Target tools (Biome / Oxc)
fd -t f 'biome\.json(c)?$' --max-depth 2
fd -t f '(\.oxlintrc\.(json|jsonc)|oxlint\.config\.(ts|js))' --max-depth 2
fd -t f '(\.oxfmtrc\.(json|jsonc)|oxfmt\.config\.(ts|js))' --max-depth 2
# Vite+ (unified Oxc config)
fd -t f 'vite\.config\.(ts|js|mjs)$' --max-depth 2
Vite+ detection: If
exists, check if it imports from
. Also check
for
in dependencies. If Vite+ is in use, its
and
blocks in
replace standalone
and
. Set
and treat Oxc config as found.
bash
# Quick Vite+ detection
grep -l "from ['\"]vite-plus['\"]" vite.config.ts 2>/dev/null
Step 2: Determine Workflow
| ESLint/Prettier | Biome | Oxc/Vite+ | Workflow |
|---|
| Found | Found | - | Migrate to Biome |
| Found | - | Found | Migrate to Oxc |
| Found | Found | Found | Ask user which target |
| Found | - | - | Ask user which target to migrate to |
| - | Found | - | Modernize Biome |
| - | - | Found | Modernize Oxc |
| - | Found | Found | Modernize both (ask which first) |
| - | - | - | Nothing to do — inform user |
Vite+ counts as Oxc in the table above. When
, all Oxc config reads/writes target the
and
blocks in
instead of standalone config files.
Ask the target choice per Asking the User:
Which tool would you like to migrate to?
1. Biome (Recommended) — All-in-one linter + formatter, single config file
2. Oxc (Oxlint + Oxfmt) — Separate linter and formatter, ESLint-compatible rule names
3. Skip — Don't migrate, just show the analysis
Migration Workflow
Runs when ESLint/Prettier configs are present.
M1: Get Tool Versions
bash
pnpm exec eslint --version 2>/dev/null || npx eslint --version 2>/dev/null
# Target-specific
pnpm exec biome --version 2>/dev/null || npx biome --version 2>/dev/null
# or
pnpm exec oxlint --version 2>/dev/null || npx oxlint --version 2>/dev/null
pnpm exec oxfmt --version 2>/dev/null || npx oxfmt --version 2>/dev/null
Read the appropriate mapping and check version staleness:
- Biome:
references/biome-eslint-mapping.json
→
- Oxc:
references/oxc-eslint-mapping.json
→
Compare installed version against
version. If installed is newer, warn that mappings may be stale and suggest running
mode.
M2: Gather Active Rules
bash
bash scripts/get-eslint-rules.sh
bash scripts/get-biome-rules.sh # or get-oxlint-rules.sh
If a script fails, fall back to reading configs manually.
M3: Load References
bash
cat references/biome-eslint-mapping.json # or oxc-eslint-mapping.json
cat references/type-aware-rules.json
For Oxc, also load
references/oxc-defaults.json
.
M4: Cross-Reference (Core Analysis)
For each active ESLint rule, classify it:
| Category | Meaning | Action |
|---|
| DISABLE | Target has "same" equivalent AND it's active | Safe to turn off in ESLint |
| REVIEW | Target has "inspired" equivalent AND it's active | Check behavior before disabling |
| ENABLE_TARGET | Target has equivalent but it's NOT active | Can switch by enabling in target config |
| ESLINT_ONLY | No target equivalent exists | Must keep in ESLint |
| TYPE_AWARE | Requires TypeScript type info | Expensive; check if target supports it |
Biome classification:
for each active ESLint rule:
1. Look up in biome-eslint-mapping.json
- Resolution: exact → "eslint-plugin-" prefix → scoped (@scope/rule)
- Core ESLint rules match directly: "no-debugger"
2. No mapping → check type-aware-rules.json → TYPE_AWARE or ESLINT_ONLY
3. Mapping exists:
a. Check if Biome rule is active (match by RULE NAME only, not category)
b. Active + "same" → DISABLE
c. Active + "inspired" → REVIEW
d. Not active → ENABLE_TARGET
Oxc classification:
for each active ESLint rule:
1. Look up in oxc-eslint-mapping.json (same resolution order)
2. No mapping → TYPE_AWARE (if in type-aware list) or ESLINT_ONLY
- Oxlint supports type-aware rules via tsgolint (check "typeAware" field)
3. Mapping exists:
a. Check if active; all Oxlint mappings are "same" relationship
b. Active → DISABLE
c. Not active → ENABLE_TARGET
M5: Prettier Migration Analysis
If Prettier config found:
Biome: Map Prettier options → Biome equivalents (see table in
).
Note:
biome migrate prettier --write
automates this.
Oxc: Oxfmt uses Prettier-compatible option names. Key differences:
- defaults to (Prettier: )
- not supported
- Built-in: , ,
Note: automates this.
Import sorting (both targets): Check if the project uses
sort rules,
@trivago/prettier-plugin-sort-imports
,
prettier-plugin-organize-imports
, or
@ianvs/prettier-plugin-sort-imports
. If so, recommend enabling the native import sorter:
- Biome:
"organizeImports": { "enabled": true }
in
- Oxfmt: (see defaults in )
Tailwind class sorting (both targets): Check if
is in project deps. If so, and if
prettier-plugin-tailwindcss
was in use, recommend enabling native sorting:
- Biome: not built-in — keep the Prettier plugin or use if available
- Oxfmt:
"sortTailwindcss": { ... }
built-in (see → )
M6: Oxc Config Initialization (Oxc Only)
If no Oxc config exists, offer to create from
references/oxc-defaults.json
.
Before writing config, check project dependencies:
bash
# Check for React
jq -r '.dependencies.react // .devDependencies.react // empty' package.json
# Check for Tailwind CSS
jq -r '.dependencies.tailwindcss // .devDependencies.tailwindcss // empty' package.json
Config assembly from defaults:
- Always: , , , from section
- Always: (, , , , )
- If React in deps: add (, , )
- Oxfmt: , from section
- If Tailwind in deps: merge → enables with class sorting for , , and common helpers (, , , , , )
Vite+ projects (): Write into
and
blocks. Do NOT create standalone config files. Example:
typescript
import { defineConfig } from 'vite-plus';
export default defineConfig({
lint: {
categories: { correctness: 'error', suspicious: 'warn', perf: 'warn' },
plugins: ['eslint', 'typescript', 'unicorn', 'oxc', 'import', 'react', 'react-hooks', 'jsx-a11y'],
rules: {
'no-console': 'warn',
'eqeqeq': 'error',
'import/no-cycle': 'error',
},
options: { typeAware: true, typeCheck: true },
},
fmt: {
singleQuote: true,
sortImports: { ignoreCase: true, order: 'asc', newlinesBetween: true },
sortTailwindcss: { functions: ['clsx', 'cn', 'cva', 'tw'] }, // if Tailwind
},
});
Standalone Oxc projects: Write
and
.
M7: Performance Analysis (Audit Mode Only)
bash
TIMING=1 pnpm exec eslint 'src/**/*.{ts,tsx}' 2>&1 | tee "$SCRATCHPAD/eslint-timing.txt"
Cross-reference slowest rules against mapping and type-aware list.
M8: Generate Migration Report
Modernize Workflow
Runs when no ESLint/Prettier configs exist but Biome and/or Oxc configs are present.
N1: Read Current Config
Read and parse the tool's config file:
- Biome: or
- Oxc standalone: and
- Vite+ (): parse and blocks from
N2: Get Installed Version
bash
pnpm exec biome --version 2>/dev/null || npx biome --version 2>/dev/null
# or
pnpm exec oxlint --version 2>/dev/null || npx oxlint --version 2>/dev/null
N3: Load Version History
bash
cat references/biome-versions.json # or oxc-versions.json
Determine which versions the user has passed through since their config was last updated. Use the installed version to find applicable changes.
N4: Check Nursery Promotions (Biome)
Scan the user's config for any rules referencing
category. Cross-reference against
→
entries for the installed version and all prior tracked versions.
For each stale nursery reference found:
| Current (stale) | Should be | Promoted in |
|---|
| | v2.4 |
| | v2.3 |
Generate a ready-to-apply diff or config patch.
N5: Suggest New Quality Rules
Biome: Check
for
in versions newer than user's mapping date. Highlight rules that are:
- Promoted to stable (non-nursery) — safe to enable
- Commonly useful (e.g., , , )
- New formatter options (e.g., in v2.4)
Oxc: Check
for
rules not yet in user's config. Suggest:
- Categories worth enabling (, )
- High-value rules from →
- New features (type-aware linting, Vue support, config extends)
N6: Suggest New Formatter Options and Sorting
Check project dependencies first:
bash
jq -r '.dependencies.tailwindcss // .devDependencies.tailwindcss // empty' package.json
Biome: Check
for
. Highlight useful additions:
formatter.trailingNewline
(v2.4)
formatter.lineEnding: "auto"
(v2.3)
- for array/object control
organizeImports.enabled: true
if not already on — replaces import-sort plugins
- Note: Biome does not have built-in Tailwind class sorting
Oxc/Vite+: Check if Oxfmt features are underutilized:
- (off by default, high value — replaces import-sort plugins)
- (if Tailwind in deps — replaces
prettier-plugin-tailwindcss
)
- formatting (off by default)
- For Vite+: and (recommended on)
N7: Generate Modernize Report
markdown
## Modernize Report
### Environment
- Tool: Biome vX.x / Oxlint vX.x / Vite+ vX.x
- Config: biome.json / .oxlintrc.json / vite.config.ts (lint + fmt)
- Reference version: X.x (installed: Y.y)
### Nursery Promotions (Biome)
X rules in your config still reference nursery/ but have been promoted:
|---------|---------|---------|
| `nursery/noSecrets` | `security/noSecrets` | v2.3 |
### New Rules Available
These rules are stable and recommended but not in your config:
|------|----------|-------------|
| `noImportCycles` | suspicious | Detect circular imports |
### New Formatter Options
|--------|-------|-------|
| `trailingNewline` | `true` | v2.4 |
### Ready-to-Apply Config Patch
(JSON diff to paste into config)
Update Workflow
Refreshes all reference files from upstream.
U1: Update biome-eslint-mapping.json
- Fetch
https://biomejs.dev/linter/rules-sources/
- Parse ESLint → Biome rule mappings
- Diff against existing, show added/removed
- Update and
U2: Update oxc-eslint-mapping.json
- Fetch
https://oxc.rs/docs/guide/usage/linter/rules
- Parse supported rules by plugin
- Diff against existing, show added/removed
- Update and
U3: Update type-aware-rules.json
bash
gh api repos/typescript-eslint/typescript-eslint/contents/packages/eslint-plugin/src/configs/flat/disable-type-checked.ts --jq '.content' | base64 -d
U4: Update version files
Check Biome and Oxc changelogs for new versions not yet tracked:
- Biome:
https://biomejs.dev/blog/
— look for new posts
- Oxc: — look for new release posts
For each new version found, add entry to
or
with:
- Promoted rules
- New rules
- New formatter options
- New features
Report Templates
Sync Mode (Migration)
markdown
## Lint Sync Report
### Environment
- ESLint: vX.x (flat/legacy config)
- Target: Biome vX.x / Oxlint vX.x + Oxfmt vX.x
- Mapping version: YYYY-MM-DD (current / stale)
- Prettier config: found / not found
### Summary
|----------|-------|
| DISABLE (safe to remove) | X |
| REVIEW (check before removing) | X |
| ENABLE_TARGET (can migrate) | X |
| ESLINT_ONLY (must keep) | X |
| TYPE_AWARE | X |
### DISABLE — Safe to Turn Off in ESLint
|-------------|------------------|
### REVIEW — Check Before Disabling
|-------------|------------------|-------|
### ENABLE_TARGET — Available to Migrate
|-------------|------------------|--------------|
### ESLINT_ONLY — Must Keep
|-------------|-------------|
### Prettier Migration (if applicable)
|----------------|--------------|--------------|----------------|--------|
### Ready-to-Paste Config
Audit Mode (adds to Sync)
markdown
### Performance Analysis
#### Top 10 Slowest Rules
|------|-----------|-------------|-------------------|
#### Coverage Statistics
- Total active ESLint rules: X
- Covered by target: X (Y%)
- ESLint-only: X (Y%)
- Type-aware: X (Y%)
#### Migration Checklist
- [ ] Disable X covered rules
- [ ] Review X "inspired" rules (Biome)
- [ ] Enable X additional target rules
- [ ] Migrate Prettier config
- [ ] Run both linters and compare output
Important Notes
- Scripts require the respective tools installed in the project
- Scripts auto-detect the package manager (pnpm/yarn/bun/npm)
- Version files track which Biome/Oxc versions introduced which changes
- Modernize workflow uses version files to detect stale nursery refs and suggest new features
- For doc lookups, use Context7 IDs from before web search
- Vite+ projects embed Oxlint/Oxfmt config in (/ blocks) — do not create standalone / alongside Vite+
- External repos accessed:
typescript-eslint/typescript-eslint
(public)
Bundled References
references/biome-eslint-mapping.json
— ESLint → Biome rule mapping (~260 entries)
references/oxc-eslint-mapping.json
— ESLint → Oxlint rule mapping (~520 entries)
references/biome-versions.json
— Biome version changelog: promotions, new rules, new options
references/oxc-versions.json
— Oxc version changelog: new rules, features, recommended config
references/oxc-defaults.json
— Opinionated Oxlint/Oxfmt defaults for initialization
references/type-aware-rules.json
— TypeScript-ESLint type-aware rules (~60 entries)
- — Context7 library IDs and documentation URLs
scripts/get-eslint-rules.sh
— Extract active ESLint rules via
scripts/get-biome-rules.sh
— Extract active Biome rules via
scripts/get-oxlint-rules.sh
— Extract active Oxlint rules