About biome
This skill helps JavaScript and TypeScript developers configure and use Biome v2 for linting, formatting, and CI checks. It also covers migration from ESLint and Prettier, version changes, and custom GritQL rules.
Key features
- 01Lint and format JS, TS, and other files
- 02Organize imports
- 03Configure biome.json
- 04Run read-only checks in CI
- 05Migrate ESLint and Prettier configurations
- 06Write custom GritQL rules
Use cases
- 01Add linting and formatting to a JS/TS project
- 02Set up a code-quality gate in CI
- 03Migrate from ESLint and Prettier
- 04Add custom lint rules to a project
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ bm629/ agent-skills --skill biomeAfter installing, type/biomein Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
references/cli.mdconfig.mdgritql-plugins.mdmigration-monorepo.mdsources.mdDetails
From the project READMEbiome — SKILL.md
Variant: standard · When to use: linting and formatting a JS/TS project with Biome v2.
Overview
Biome is a single Rust binary that lints, formats, and organizes imports for JavaScript, TypeScript, JSX, JSON, CSS, and GraphQL — one tool and one biome.json in place of the ESLint + Prettier stack. It is the JS/TS analog of Python's ruff: fast, opinionated defaults, one config. This skill covers installing Biome (v2), writing biome.json, the current CLI (including the biome ci gate), migrating an existing ESLint/Prettier setup, the v1→v2 changes that trip up stale knowledge, and authoring custom lint rules as GritQL plugins. Verified against Biome v2; confirm the exact current version when you install.
When to activate
- ✅ Adding lint + format to a JS/TS project (new or replacing ESLint/Prettier).
- ✅ Writing or fixing a
biome.json(formatter, linter rules, import organizing, VCS, overrides). - ✅ Wiring a lint/format CI gate.
- ✅ Migrating from ESLint/Prettier, or authoring a custom rule as a GritQL plugin.
Do NOT activate when:
- You need to wire Biome as a task in a Turborepo/pnpm pipeline — compose with the
turboreposkill; this skill owns Biome itself, not the task graph. - The project is Python — that's
ruff(Biome is the JS/TS counterpart, named here only as the analog).
Workflow
Step 1: Install + init
npm install --save-dev --save-exact @biomejs/biome # i.e. -D -E
npx biome init # writes biome.json
Step 2: Configure biome.json
{
"$schema": "https://biomejs.dev/schemas/<version>/schema.json",
"vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
"files": { "includes": ["src/**", "!**/dist"] },
"formatter": { "enabled": true, "indentStyle": "space", "lineWidth": 100 },
"linter": { "enabled": true, "rules": { "recommended": true } },
"assist": { "enabled": true, "actions": { "source": { "organizeImports": "on" } } }
}
(biome init writes $schema with the version-pinned URL — don't ship the <version> literal.) Full schema — rule groups + linter.domains, language blocks, overrides, monorepo extends/root — in references/config.md.
Step 3: Run it
npx biome check --write . # lint + format + organize imports, apply SAFE fixes
npx biome check --write --unsafe . # also apply unsafe fixes
npx biome format --write . # format only; npx biome lint . # lint only
biome check runs all three (format, lint, import sort). Full command/flag reference + the v1→v2 CLI deltas: references/cli.md.
Step 4: CI gate
npx biome ci . # read-only: format + lint + import-sort checks, never writes
Use biome ci in CI (the analog of ruff check), never check --write (which mutates). Wire it as the lint/format job; defer the pipeline/caching to the turborepo skill.
Step 5: Migrate from ESLint / Prettier (if applicable)
npx biome migrate eslint --write # ports .eslintrc / flat config + .eslintignore
npx biome migrate prettier --write # ports .prettierrc
Details + caveats: references/migration-monorepo.md.
Step 6: Custom rules (optional) — GritQL plugins
Register a .grit plugin in biome.json plugins and write the pattern; full authoring guide (pattern syntax, register_diagnostic, a complete example, limitations) in references/gritql-plugins.md. Prefer a built-in rule first; reach for a plugin only when no rule covers the case.
Rules
Hard rules (never violate):
- Use the v2 CLI.
--write/--write --unsafeapply fixes; the v1--apply/--apply-unsafeare gone. Emitting--applyis the #1 stale-knowledge error — see Gotchas. biome ciis the CI gate, notcheck --write. CI must be read-only;check --writemutates the tree.- One
biome.jsonper project (useextendsfor nested/monorepo configs). Don't also run ESLint/Prettier for the same concerns — Biome replaces them.
Preferences (override-able):
- Biome's formatter defaults to tabs and a 2-space width with
lineWidth80. If the team standardizes on spaces (e.g. coming from Prettier), setformatter.indentStyle/lineWidthexplicitly. - Enable
vcs.useIgnoreFileso Biome respects.gitignore. - Start from
rules.recommendedand tighten per rule group as needed.
Gotchas
--applywas removed (v1→v2). v1 usedbiome check --apply/--apply-unsafe; v2 uses--write/--write --unsafe(--fixis an alias of--write). Stale snippets and old muscle memory emit--apply, which now errors. Seereferences/cli.md.- Import organizing moved. v1's top-level
organizeImportsis gone; in v2 it's an assist action underassist.actions.source.organizeImports. A v1-shaped config silently won't organize imports. include/ignore→includes(v2). v2'sfiles.includesis a single glob list using!-prefixed negations, replacing v1's separateinclude/ignore. A v1-shapedfilesblock is wrong.- Formatter default is tabs. Prettier users expecting spaces get tabs unless they set
indentStyle: "space".biome migrate prettieraligns it, but a freshbiome initdoes not. - GritQL plugins target JS and CSS only (currently). A plugin for another language won't run.
Anti-patterns
- Running ESLint + Prettier AND Biome for the same files. Double tooling, conflicting fixes, slower. Biome replaces them — migrate, don't stack.
biome check --writein CI. CI mutates the tree and can mask drift. Usebiome ci.- Reaching for a GritQL plugin when a built-in rule exists. Check the rule groups first; plugins are for genuinely custom checks.
- Duplicating the Turborepo pipeline here. Wiring Biome as a cached task belongs to the
turboreposkill; this skill stops at the Biome command.
Output
A configured biome.json plus the lint/format commands wired locally (biome check --write) and in CI (biome ci) — optionally migrated from an ESLint/Prettier setup and extended with custom GritQL rules. The consumer is the developer workflow and the CI gate that enforce a consistent, lint-clean codebase.
Related
turborepo— runbiome ci/checkas a cached pipeline task; this skill owns Biome, that one owns the task graph.vite— the build the linted/formatted code typically ships in.ruff— the Python lint+format analog Biome mirrors conceptually (different tool).
Progressive disclosure
references/config.md— load when writingbiome.json: full top-level schema, formatter/linter/assist options, rule groups,overrides, monorepoextends/root, and the v2 config-shape changes.references/cli.md— load when running Biome or wiring CI: all commands + flags, the--write/cisemantics, and the v1→v2 CLI delta table.references/gritql-plugins.md— load when authoring a custom rule: plugin registration, GritQL pattern syntax,register_diagnostic, a complete example, and limitations.references/migration-monorepo.md— load when migrating from ESLint/Prettier or configuring a monorepo: themigratecommands + caveats and theextends/rootmonorepo model.references/sources.md— research provenance.
Body budget
description≤ 1,024 chars; body ≤ ~500 lines / 5,000 tokens; heavy content inreferences/.