Releases: biomejs/biome
Biome CLI v2.4.4
2.4.4
Patch Changes
-
#9150
6946835Thanks @dyc3! - Fixed #9138: Astro files containing---in HTML content (e.g.,<h1>---Hi</h1>) are now parsed correctly, both when a frontmatter block is present and when there is no frontmatter at all. -
#9150
aa6f837Thanks @dyc3! - Fixed #9138: The HTML parser incorrectly failing to parse bracket characters ([and]) in text content (e.g.<div>[Foo]</div>). -
#9151
c0d4b0cThanks @dyc3! - Fixed parsing of Svelte directive keywords (use,style) when used as plain text content in HTML/Svelte files. Previously,<p>use JavaScript</p>or<p>style it</p>would incorrectly produce a bogus element instead of proper text content. -
#9162
7f1e060Thanks @dyc3! - Fixed #9161: The Vue parser now correctly handles colon attributes likexlink:hrefandxmlns:xlinkby parsing them as single attributes instead of splitting them into separate tokens. -
#9164
458211bThanks @dyc3! - Fixed #9161: ThenoAssignInExpressionsrule no longer flags assignments in Vue v-on directives (e.g.,@click="counter += 1"). Assignments in event handlers are idiomatic Vue patterns and are now skipped by the rule.
What's Changed
- chore(scss): cherry-picks by @denbezrukov in #9149
- fix(parse/html): don't lex square brackets as special tokens in contexts where they don't mean anything by @dyc3 in #9150
- refactor(parse/html): use token_set! instead of matches! for svelte keywords and directives helpers by @dyc3 in #9148
- fix(parse/html): don't lex "use" as
USE_KWwhen in html text content by @dyc3 in #9151 - feat(css): enhance SCSS qualified name detection by @denbezrukov in #9159
- chore(html): more html benchmarks by @dyc3 in #8153
- fix(parse/html/vue): don't treat
:as special token outside of vue directives by @dyc3 in #9162 - feat(lint/vue): automatically ignore
noAssignInExpressionsfor vue v-on directives by @dyc3 in #9164 - ci: release by @github-actions[bot] in #9160
Full Changelog: https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.3...@biomejs/biome@2.4.4
Biome CLI v2.4.3
2.4.3
Patch Changes
-
#9120
aa40fc2Thanks @ematipico! - Fixed #9109, where the GitHub reporter wasn't correctly enabled whenbiome ciruns on GitHub Actions. -
#9128
8ca3f7fThanks @dyc3! - Fixed #9107: The HTML parser can now correctly parse Astro directives (client/set/class/is/server), which fixes the formatting for Astro directives. -
#9124
f5b0e8dThanks @ematipico! - Fixed #8882 and #9108: The Astro frontmatter lexer now correctly identifies the closing---fence when the frontmatter contains multi-line block comments with quote characters, strings that mix quote types (e.g."it's"), or escaped quote characters (e.g."\"). -
#9142
3ca066bThanks @THernandez03! - Fixed #9141: ThenoUnknownAttributerule no longer reportsclosedbyas an unknown attribute on<dialog>elements. -
#9126
792013eThanks @ematipico! - Added missing Mocha globals to theTestdomain:context,run,setup,specify,suite,suiteSetup,suiteTeardown,teardown,xcontext,xdescribe,xit, andxspecify. These are injected by Mocha's BDD and TDD interfaces and were previously flagged as undeclared variables in projects using Mocha. -
#8855
6918c9eThanks @ruidosujeira! - Fixed #8840. Now the Biome CSS parser correctly parsesnot + scroll-stateinside@containerqueries. -
#9111
4fb55cfThanks @Jayllyz! - Slightly improved performance ofnoIrregularWhitespaceby adding early return optimization and simplifying character detection logic. -
#8975
086a0c5Thanks @FrankFMY! - Fixed #8478:useDestructuringno longer suggests destructuring when the variable has a type annotation, likeconst foo: string = object.foo.
What's Changed
- perf(lint): optimize noIrregularWhitespace rule by @Jayllyz in #9111
- fix(cli): use github reporter in github actions env by @ematipico in #9120
- fix: add more globals for mocha by @ematipico in #9126
- fix(parse/html): astro fence by @ematipico in #9124
- fix(linter): skip useDestructuring for variables with type annotations by @FrankFMY in #8975
- fix(parser): accept scroll-state(...) in @container not queries by @ruidosujeira in #8855
- fix(noUnknownAttribute): add
closedbyas a valid attribute for<dialog>by @THernandez03 in #9142 - feat(parse/html): parse astro directives by @dyc3 in #9128
- ci: release by @github-actions[bot] in #9116
New Contributors
- @THernandez03 made their first contribution in #9142
Full Changelog: https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.2...@biomejs/biome@2.4.3
Biome CLI v2.4.2
2.4.2
Patch Changes
-
#9103
fc9850cThanks @dyc3! - Fixed #9098:useImportTypeno longer incorrectly flags imports used in Svelte control flow blocks ({#if},{#each},{#await},{#key}) as type-only imports. -
#9106
f4b7296Thanks @dyc3! - Updated rule source metadata for rules fromhtml-eslint. -
#8960
4a5ff40Thanks @abossenbroek! - Added the nursery rulenoConditionalExpect. This rule disallows conditionalexpect()calls inside tests, which can lead to tests that silently pass when assertions never run.// Invalid - conditional expect may not run test("conditional", async ({ page }) => { if (someCondition) { await expect(page).toHaveTitle("Title"); } }); // Valid - unconditional expect test("unconditional", async ({ page }) => { await expect(page).toHaveTitle("Title"); });
-
#8960
4a5ff40Thanks @abossenbroek! - Added the nursery rulenoPlaywrightElementHandle. Prefers locators to element handles.const el = await page.$(".btn");
-
#8960
4a5ff40Thanks @abossenbroek! - Added the nursery rulenoPlaywrightEval. Disallowspage.$eval()andpage.$$eval()methods.await page.$eval(".btn", (el) => el.textContent);
-
#8960
4a5ff40Thanks @abossenbroek! - Added the nursery rulenoPlaywrightForceOption. Disallows theforceoption on user interactions.await locator.click({ force: true });
-
#8960
4a5ff40Thanks @abossenbroek! - Added the nursery rulenoPlaywrightMissingAwait. Enforces awaiting async Playwright APIs.const el = page.locator(".btn"); el.click(); // Missing await
-
#8960
4a5ff40Thanks @abossenbroek! - Added the nursery rulenoPlaywrightNetworkidle. Disallows deprecatednetworkidlewait option.await page.goto(url, { waitUntil: "networkidle" });
-
#8960
4a5ff40Thanks @abossenbroek! - Added the nursery rulenoPlaywrightPagePause. Disallowspage.pause()debugging calls in committed code.await page.pause();
-
#8960
4a5ff40Thanks @abossenbroek! - Added the nursery rulenoPlaywrightUselessAwait. Disallows unnecessaryawaiton synchronous Playwright methods.// Incorrect - locator() is synchronous const loc = await page.locator(".btn");
-
#8960
4a5ff40Thanks @abossenbroek! - Added the nursery rulenoPlaywrightWaitForNavigation. Prefers modern navigation APIs over deprecatedwaitForNavigation().await page.waitForNavigation();
-
#8960
4a5ff40Thanks @abossenbroek! - Added the nursery rulenoPlaywrightWaitForSelector. Prefers locators over deprecatedwaitForSelector().await page.waitForSelector(".btn");
-
#8960
4a5ff40Thanks @abossenbroek! - Added the nursery rulenoPlaywrightWaitForTimeout. Disallows hard-coded timeouts withwaitForTimeout().await page.waitForTimeout(5000);
-
#8960
4a5ff40Thanks @abossenbroek! - EnhancednoSkippedTeststo detect Playwright patterns (.fixme,test.describe,test.step, bracket notation, bare calls). ConsolidatednoPlaywrightSkippedTestinto this rule. -
#9101
0c0fb6fThanks @siketyan! - Fixed#9080: ThenoUnusedVariablesrule no longer reports a top-levelPropsinterface or type alias as unused in Astro files. -
#8960
4a5ff40Thanks @abossenbroek! - Added the nursery ruleuseExpect. This rule ensures that test functions contain at least oneexpect()assertion.// Invalid - test without assertion test("no assertion", async ({ page }) => { await page.goto("/"); }); // Valid - test with assertion test("has assertion", async ({ page }) => { await expect(page).toHaveTitle("Title"); });
-
#8960
4a5ff40Thanks @abossenbroek! - Added the nursery ruleusePlaywrightValidDescribeCallback. Validates that describe callback signatures are not async.test.describe("suite", async () => {});
What's Changed
- fix(lint): don't report
Propsinterface as unused in Astro files by @siketyan in #9101 - fix(service): parse text expressions in svelte control flow blocks by @dyc3 in #9103
- feat(migrate): more metadata for rules from
html-eslintby @dyc3 in #9106 - feat(lint): add Playwright ESLint rules by @abossenbroek in #8960
- ci: release by @github-actions[bot] in #9104
New Contributors
- @abossenbroek made their first contribution in #8960
Full Changelog: https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.1...@biomejs/biome@2.4.2
Biome CLI v2.4.1
2.4.1
Patch Changes
-
#9092
6edd600Thanks @ematipico! - Fixed #9052. This PR reverts changes introduced by #8519, which caused unwanted changes on how paths are resolved. -
#9091
3bf674dThanks @ematipico! - Fixed #9090, where SCSS files were incorrectly processed by Biome. This was a regressions caused by the latest developments for supporting SCSS out of the box. -
#9100
66931a8Thanks @siketyan! - Fixed #9081: ThenoUnknownPseudoElementrule no longer reports false positives for any known pseudo elements in CSS modules. This was a regression introduced in v2.4.0. -
#9102
d01b903Thanks @ematipico! - Fixed #9095, where Biome didn't print anything in stdin mode. This was a regression caused by a recent, internal refactor.
What's Changed
- chore: docs that break website by @ematipico in #9077
- chore(deps): update dependency @types/node to v24.10.13 by @renovate[bot] in #9083
- chore(deps): update dependency rust to v1.93.1 by @renovate[bot] in #9084
- chore(deps): update github-actions by @renovate[bot] in #9086
- chore(deps): update dependency tombi to v0.7.28 by @renovate[bot] in #9085
- feat(markdown): port snapshots from prettier by @tidefield in #9067
- fix(core): scss handling by @ematipico in #9091
- revert(core): includes resolution by @ematipico in #9092
- chore(deps): update rust crate jiff to 0.2.20 by @renovate[bot] in #9088
- chore(deps): update rust crate libc to 0.2.182 by @renovate[bot] in #9089
- fix(cli): stdin regression by @ematipico in #9102
- fix(lint): regression of the
noUnknownPseudoElementrule by @siketyan in #9100 - ci: release by @github-actions[bot] in #9094
Full Changelog: https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.0...@biomejs/biome@2.4.1
Biome CLI v2.4.0
2.4.0
Minor Changes
-
#8964
0353fa0Thanks @dyc3! - Addedignoreoption to theuseHookAtTopLevelrule.You can now specify function names that should not be treated as hooks, even if they follow the
use*naming convention.Example configuration:
{ "linter": { "rules": { "correctness": { "useHookAtTopLevel": { "options": { "ignore": ["useDebounce", "useCustomUtility"] } } } } } } -
#8769
d0358b0Thanks @rahuld109! - Added the ruleuseAnchorContentfor HTML to enforce that anchor elements have accessible content for screen readers. The rule flags empty anchors, anchors with only whitespace, and anchors where all content is hidden witharia-hidden. Anchors witharia-labelortitleattributes providing a non-empty accessible name are considered valid. -
#8742
6340ce6Thanks @rahuld109! - Added the ruleuseMediaCaptionto the HTML language. Enforces thataudioandvideoelements have atrackelement withkind="captions"for accessibility. Muted videos are allowed without captions. -
#8621
d11130bThanks @Netail! - Added support for multiple reporters, and the ability to save reporters on arbitrary files.Combine two reporters in CI
If you run Biome on GitHub, take advantage of the reporter and still see the errors in console, you can now use both reporters:
biome ci --reporter=default --reporter=github
Save reporter output to a file
With the new
--reporter-fileCLI option, it's now possible to save the output of all reporters to a file. The file is a path,
so you can pass a relative or an absolute path:biome ci --reporter=rdjson --reporter-file=/etc/tmp/report.json biome ci --reporter=summary --reporter-file=./reports/file.txt
You can combine these two features. For example, have the
defaultreporter written on terminal, and therdjsonreporter written on file:biome ci --reporter=default --reporter=rdjson --reporter-file=/etc/tmp/report.json
The
--reporterand--reporter-fileflags must appear next to each other, otherwise an error is thrown. -
#8399
ab88099Thanks @ematipico! - The Biome CSS parser is now able to parse Vue SFC syntax such as:slottedand:deep. These pseudo functions are only correctly parsed when the CSS is defined inside.vuecomponents. Otherwise, Biome will a emit a parse error.This capability is only available when
experimentalFullHtmlSupportedEnabledis set totrue. -
#8663
3dfea16Thanks @ematipico! - Added support for Cursor files. When Biome sees a Cursor JSON file, it will parse it with comments enabled and trailing commas enabled:$PROJECT/.cursor/%APPDATA%\Cursor\User\on Windows~/Library/Application Support/Cursor/User/on macOS~/.config/Cursor/User/on Linux
-
#8723
fe2c642Thanks @cbstns! - Added JSON as a target language for GritQL pattern matching. You can now write Grit plugins for JSON files.This enables users to write GritQL patterns that match against JSON files, useful for:
- Searching and transforming JSON configuration files
- Enforcing patterns in
package.jsonand other JSON configs - Writing custom lint rules for JSON using GritQL
Example patterns:
Match all key-value pairs:
language json pair(key = $k, value = $v)Match objects with specific structure:
language json JsonObjectValue()Supports both native Biome AST names (
JsonMember,JsonObjectValue) and TreeSitter-compatible names (pair,object,array) for compatibility with existing Grit patterns.For more details, see the GritQL documentation.
-
#8814
4d9c676Thanks @Netail! - Addedignoreoption tonoUnknownProperty. If an unknown property name matches any of the items provided inignore, a diagnostic won't be emitted. -
#8631
4d8f19dThanks @Netail! - Add a new reporter--reporter=sarif, that emits diagnostics using the SARIF format. -
#8270
4f7909dThanks @lucasweng! - Added theuseIframeTitlelint rule for HTML. The rule enforces the usage of thetitleattribute for theiframeelement.Invalid:
<iframe></iframe> <iframe title=""></iframe>
Valid:
<iframe title="title"></iframe>
-
#8164
1d25856Thanks @ematipico! - Added a new assist actionuseSortedInterfaceMembersthat sorts TypeScript interface members, for readability.It includes an autofix.
Invalid example.
interface MixedMembers { z: string; a: number; (): void; y: boolean; }
Valid example (after using the assist).
interface MixedMembers { a: number; y: boolean; z: string; (): void; }
-
#8647
4c7c06fThanks @siketyan! - It's now possible to provide the stacktrace for a fatal error. The stacktrace is only available when the environment variableRUST_BACKTRACE=1is set, either via the CLI or exported$PATH. This is useful when providing detailed information for debugging purposes:RUST_BACKTRACE=1 biome lint
-
#7961
a04c8dfThanks @siketyan! - The Biome Language Server now reports progress while scanning files and dependencies in the project. -
#8289
a9025d4Thanks @theshadow27! - Fixed #8024. The ruleuseIterableCallbackReturnnow supports acheckForEachoption. When set tofalse, the rule will skip checking forforEach()callbacks for returning values. -
#8690
e06e5d1Thanks @ematipico! - Added the ruleuseValidLangto the HTML language. -
#7847
e90b14fThanks @Jagget! - Added support forjsxFactoryandjsxFragmentFactory.Biome now respectsjsxFactoryandjsxFragmentFactorysettings fromtsconfig.jsonwhen using the classic JSX runtime, preventing false positive noUnusedImports errors for custom JSX libraries like Preact.// tsconfig.json { compilerOptions: { jsx: "react", jsxFactory: "h", jsxFragmentFactory: "Fragment", }, }
// Component.jsx import { h, Fragment } from "preact"; function App() { return <div>Hello</div>; }
-
#8071
7f5bcf4Thanks @ematipico! - Added new CLI options to the commandslsp-proxyandstartthat allow to control the Biome file watcher.--watcher-kindControls how the Biome file watcher should behave. By default, Biome chooses the best watcher strategy for the
current OS, however sometimes this could result in some issues, such as folders locked.The option accepts the current values:
recommended: the de...
Biome CLI v2.3.15
2.3.15
Patch Changes
-
#9019
043b67cThanks @dyc3! - Added the lint rulenoNestedPromises. This rule detects nested.then()or.catch()calls that could be refactored into flat promise chains.// Invalid: nested promise that can be flattened doThing().then(function () { return doOtherThing().then(console.log); }); // Valid: flat promise chain doThing() .then(() => doOtherThing()) .then(console.log);
The rule intelligently allows nesting when the inner callback references variables from the outer scope, as these cases cannot be safely flattened.
-
#9029
6ebf6c6Thanks @ff1451! - Added the nursery rulenoUselessReturn. The rule reports redundantreturn;statements that don't affect the function's control flow.// Invalid: return at end of function is redundant function foo() { doSomething(); return; }
-
#9017
8bac2daThanks @mdevils! - Reverted a behavior change inuseExhaustiveDependenciesthat was accidentally included as part of the #8802 fix. The change made method calls on objects (e.g.,props.data.forEach(...)) report only the object (props.data) as a missing dependency instead of the full member expression. This behavior change will be reconsidered separately. -
#9005
c8dbbbeThanks @corvid-agent! - Fixed #8790: ThenoAssignInExpressionsrule no longer reports a false positive when an assignment is used as the expression body of an arrow function (e.g.,const f = b => a += b). -
#8519
ccdc602Thanks @ruidosujeira! - Fixed #8518, where globally excluded files in a monorepo were still being processed when using"extends": "//".When a package-level configuration extends the root configuration with
"extends": "//", glob patterns (such as those infiles.includes) are now correctly resolved relative to the project root directory, instead of the current workspace directory. -
#9033
0628e0aThanks @mdevils! - Fixed #8967. useExhaustiveDependencies no longer reports false positives for variables destructured from a rest pattern. -
#9023
8ef9d1dThanks @siketyan! - Fixed #9020: Whenjavascript.jsxRuntimeis set toreactClassic,noUnusedImportsanduseImportTyperules now allow importing theReactidentifier from a package other thanreact. This aligns the behavior withtsc(--jsx=react), which also allows importingReactfrom any package. -
#8646
16fd71dThanks @siketyan! - Fixed #8605: Text expressions in some template languages ({{ expr }}or{ expr }) at the top level of an HTML document no longer causes panicking. -
#8930
51c158eThanks @ANKANJAGTAP! - Fixed #8917
useExhaustiveDependencies now correctly detects JSX component identifiers as hook dependencies. -
#9009
7d229c7Thanks @Netail! - Fixed typo in noPositiveTabindex's quick fix text. -
#8758
8c789f1Thanks @Pranav2612000! - Updated the useJsxKeyInIterable rule to not run inside Map constructors -
#8977
bbe0e0cThanks @FrankFMY! - Fixed #4888.
noUnusedImports now addsexport {}when removing the last import in a TypeScript file to prevent it from becoming an ambient module. This does not apply to embedded scripts in Vue, Svelte, or Astro files, which are already in a module context. -
#9016
9d4cfa3Thanks @dyc3! - Added eslint migration metadata for the rules@typescript/no-var-requires,@typescript/keyword-spacing,@typescript/func-call-spacing,vue/keyword-spacing,vue/func-call-spacing, andunicorn/empty-brace-spaces, -
#8848
2cba2b3Thanks @LouisLau-art! - Fixed #8845. NowuseGenericFontNamesdoesn't trigger whenfontis declared inside the@supportsat-rule. -
#8997
a5f3212Thanks @mldangelo! - Fixed #8476.
useAwaitThenable no longer reports false positives forawaiton call expressions whose return type cannot be resolved (e.g., cross-module function calls to Node.js builtins or npm packages). -
#8978
cc7a478Thanks @FrankFMY! - Fixed #8645.
useAwait no longer reportsasyncgenerator functions that useyield*, sinceyield*in an async generator delegates to anAsyncIterableand requires theasyncmodifier.
What's Changed
- docs: fix website sync by @dyc3 in #8957
- chore(deps): update rust crate git2 to v0.20.4 [security] by @renovate[bot] in #8965
- fix: jsx dependency detection in useexhaustivedependencies (#8917) by @ANKANJAGTAP in #8930
- chore(doc): update formatter contributing doc by @tidefield in #8972
- fix(useAwait): treat yield* as async operation in async generators by @FrankFMY in #8978
- fix(css): ignore @supports queries in useGenericFontNames rule by @LouisLau-art in #8848
- fix(html/parser): distinguish interpolations inside and outside tags by @siketyan in #8646
- chore(deps): update rust:1.93.0-bookworm docker digest to d0a4aa3 by @renovate[bot] in #8999
- chore(deps): update rust:1.93.0-bullseye docker digest to 3ebcc2d by @renovate[bot] in #9000
- fix(codegen): remove duplicate preamble in generated analyzer files by @mldangelo in #8993
- chore(deps): update rust crate anyhow to 1.0.101 by @renovate[bot] in #9004
- chore(deps): update rust crate bpaf to 0.9.23 by @renovate[bot] in #9006
- chore(deps): update rust crate insta to 1.46.3 by @renovate[bot] in #9007
- chore(deps): update dependency tombi to v0.7.27 by @renovate[bot] in #9002
- chore(deps): update github-actions by @renovate[bot] in #9003
- chore(deps): update dependency @types/node to v24.10.11 by @renovate[bot] in #9001
- fix(js_analyze): typo in noPositiveTabindex's action suggestion by @Netail in #9009
- fix(useAwaitThenable): treat unresolved call expressions as uninferred by @mldangelo in #8997
- fix(linter):...
Biome CLI v2.3.14
2.3.14
Patch Changes
-
#8921
29e2435Thanks @siketyan! - Fixed #8759: TheuseConsistentTypeDefinitionsrule no longer converts empty object type declarations into interfaces, as it will conflict with thenoEmptyInterfacerule and can cause an infinite loop when both rules are enabled. -
#8928
ccaeac4Thanks @taga3s! - Added the nursery ruleuseGlobalThis. This rule enforces usingglobalThisoverwindow,selfandglobal. -
#8602
9a18daaThanks @dyc3! - Added the new nursery rulenoVueArrowFuncInWatch. This rule forbids using arrow functions in watchers in Vue components, because arrow functions do not give access to the component instance (viathis), while regular functions do. -
#8905
9b1eea8Thanks @ryan-m-walker! - Fixed #8428: Improved parsing recovery when encountering qualified rules inside CSS@pageat-rule blocks. -
#8900
f788cffThanks @mdevils! - Fixed #8802:useExhaustiveDependenciesnow correctly suggests dependencies without including callback-scoped variables or method names.When accessing object properties with a callback-scoped variable, only the object path is suggested:
// Now correctly suggests `props.value` instead of `props.value[day]` useMemo(() => { return WeekdayValues.filter((day) => props.value[day]); }, [props.value]);
When calling methods on objects, only the object is suggested as a dependency:
// Now correctly suggests `props.data` instead of `props.data.forEach` useMemo(() => { props.data.forEach((item) => console.log(item)); }, [props.data]);
-
#8913
e1e20eaThanks @dyc3! - Fixed #8363: HTML parser no longer crashes when encountering a<character followed by a digit in text content (e.g.,<12 months). The parser now correctly emits an "Unescaped<bracket character" error instead of treating<12as a tag name and crashing. -
#8910
2fb63a4Thanks @dyc3! - Fixed #8774: Type aliases with generic parameters that haveextendsconstraints now properly indent comments after the equals sign.Previously, comments after the
=in type aliases withextendsconstraints were not indented:-type A<B, C extends D> = // Some comment -undefined; +type A<B, C extends D> = + // Some comment + undefined;
-
#8916
ea4bd04Thanks @ryan-m-walker! - Fixed #4013, where comments in member chains caused unnecessary line breaks.// Before aFunction.b().c.d(); // After aFunction.b().c.d();
-
#8945
fa66fe3Thanks @fireairforce! - Fixed #8354: Don't remove quotes when type memeber is new.// Input: type X = { "new"(): string; "foo"(): string; }; // Format Output: type X = { "new()": string; foo(): string; };
-
#8927
0ef3da5Thanks @littleKitchen! - Fixed #8907:useExhaustiveDependenciesnow correctly recognizes stable hook results (likeuseStatesetters anduseRefvalues) when declared withlet. -
#8931
4561751Thanks @koshin01! - Added the new nursery rulenoRedundantDefaultExport, which flags redundant default exports where the default export references the same identifier as a named export. -
#8900
f788cffThanks @mdevils! - Fixed #8883:useExhaustiveDependenciesno longer produces false positives when props are destructured in the function body of arrow function components without parentheses around the parameter.type Props = { msg: string }; // Arrow function without parentheses around `props` const Component: React.FC<Props> = (props) => { const { msg } = props; // Previously, this incorrectly reported `msg` as unnecessary useEffect(() => console.log(msg), [msg]); };
-
#8861
3531687Thanks @dyc3! - Added thenoDeprecatedMediaTypeCSS rule to flag deprecated media types liketvandhandheld. -
#8775
7ea71cdThanks @igas! - Fixed thenoUnnecessararyConditionsrule to prevent trigger for optional fallback patterns. -
#8860
95f1eeaThanks @dyc3! - Added the nursery rulenoHexColors, which flags the use of hexadecimal color codes in CSS and suggests using named colors or RGB/RGBA/HSL/HSLA formats instead. -
#8786
d876a38Thanks @Bertie690! - Added the nursery ruleuseConsistentMethodSignatures.
Inspired by the similarly named version fromtypescript-eslint, this rule aims to enforce a consistent style for methods used inside object types and interfaces.Examples
Invalid code with
styleset to"property"(the default):interface Foo { method(a: string): void; }
Invalid code with
styleset to"method":type Bar = { prop: (a: string) => void; }
-
#8864
5e97119Thanks @dyc3! - Improved the summary provided bybiome migrate eslintto be clearer on why rules were not migrated. Biome now specifies a reason when a rule is not migrated, such as being incompatible with the formatter or not implemented yet. This helps users make more informed decisions when migrating their ESLint configurations to Biome. -
#8924
99b4cd1Thanks @tmohammad78! - Fixed #8920:noUnknownFunctionnow knows aboutsibling-count, andsibling-indexcss functions -
#8900
f788cffThanks @mdevils! - Fixed #8885:useExhaustiveDependenciesno longer incorrectly reports variables as unnecessary dependencies when they are derived from expressions containing post/pre-increment operators (++/--) or compound assignment operators (+=,-=, etc.).let renderCount = 0; export const MyComponent = () => { // `count` is now correctly recognized as a required dependency // because `renderCount++` can produce different values between renders const count = renderCount++; useEffect(() => { console.log(count); }, [count]); // no longer reports `count` as unnecessary };
-
#8619 [
d78e01d](...
Biome CLI v2.3.13
2.3.13
Patch Changes
-
#8815
f924f23Thanks @dyc3! - ImproveduseVueValidVOnto be more closely aligned with the source rule. It will now properly allow modifiers for all possible keyboard events. It should have better performance when there are no violations of the rule as well.Now treated valid:
<div @keydown.arrow-down="handler"></div> <div @keydown.a="handler"></div> <div @keydown.b="handler"></div> <div @keydown.27="foo"></div>
-
#8856
85f81f9Thanks @dyc3! - Fixed #8710: Biome now parses Vue dynamic slot shorthand arguments that use template literals in[]. -
#8850
2a190e0Thanks @dyc3! - Fixed #8708: Tailwind@utilitydirectives now parse functional utility names likepx-*when Tailwind directives are enabled. -
#8863
79386e0Thanks @dyc3! - Fixed an issue withbiome migrate eslintwhere it couldn't detect rules for CSS, GraphQL, and HTML. -
#8771
6f56b6eThanks @lghuahua! - Fix the--reporter=summaryoutput incorrectly merging and displaying wrong issue counts for different rules. Fixes #8730 -
#8714
ac3a71fThanks @Netail! - Added new nursery ruleuse-consistent-enum-value-type. This rule disallows enums from having both number and string members.
What's Changed
- fix(dx/codegen): don't insert module into
biome_rule_options/src/lib.rsif it already exists by @dyc3 in #8847 - feat(js_analyze): implement useConsistentEnumValueType by @Netail in #8714
- fix(parse/html/vue): parse dynamic slot directives that contain quotes by @dyc3 in #8856
- fix(parse/css): improve parsing of
@utilitynames by @dyc3 in #8850 - fix(cli): improve RuleName ordering and update summary snapshots close #8730 by @lghuahua in #8771
- fix(useVueValidVOn): align more with source rule, also use phf hash sets for perf by @dyc3 in #8815
- fix(migrate): fix migrate command not picking up rules for css, graphql, html by @dyc3 in #8863
- chore(deps): update dependency tombi to v0.7.23 by @renovate[bot] in #8865
- chore(deps): update pnpm to v10.28.1 by @renovate[bot] in #8866
- chore(deps): update rust crate proc-macro2 to 1.0.106 by @renovate[bot] in #8867
- chore(deps): update rust crate quote to 1.0.44 by @renovate[bot] in #8868
- fix(deps): update @biomejs packages by @renovate[bot] in #8869
- chore(deps): update rust crate schemars to 1.2.0 by @renovate[bot] in #8875
- chore(deps): update @biomejs packages by @renovate[bot] in #8872
- chore(deps): update github-actions by @renovate[bot] in #8873
- chore(deps): update typescript-eslint monorepo to v8.53.1 by @renovate[bot] in #8877
- fix(deps): update dependency prettier to v3.8.1 by @renovate[bot] in #8878
- chore(deps): update rust crate tokio to 1.49.0 by @renovate[bot] in #8876
- ci: release by @github-actions[bot] in #8853
New Contributors
Full Changelog: https://github.com/biomejs/biome/compare/@biomejs/biome@2.3.12...@biomejs/biome@2.3.13
Biome CLI v2.3.12
2.3.12
Patch Changes
-
#8653
047576dThanks @dyc3! - Added new nursery rulenoDuplicateAttributesto forbid duplicate attributes in HTML elements. -
#8648
96d09f4Thanks @BaeSeokJae! - Added a new nursery rulenoVueOptionsApi.Biome now reports Vue Options API usage, which is incompatible with Vue 3.6's Vapor Mode.
This rule detects Options API patterns in<script>blocks,defineComponent(), andcreateApp()calls,
helping prepare codebases for Vapor Mode adoption.For example, the following now triggers this rule:
<script> export default { data() { return { count: 0 }; }, }; </script>
-
#8832
b08270bThanks @Exudev! - Fixed #8809, #7985, and #8136: thenoSecretsrule no longer reports false positives on common CamelCase identifiers likepaddingBottom,backgroundColor,unhandledRejection,uncaughtException, andIngestGatewayLogGroup.The entropy calculation algorithm now uses "average run length" to distinguish between legitimate CamelCase patterns (which have longer runs of same-case letters) and suspicious alternating case patterns (which have short runs).
-
#8793
c19fb0eThanks @TheBaconWizard! - Properly handleparametersmetavariables forarrow_functionGritQL queries. The followingbiome searchcommand no longer throws an error:biome search 'arrow_function(parameters=$parameters, body=$body)' -
#8561
981affbThanks @wataryooou! - FixednoUnusedVariablesto ignore type parameters declared in ambient contexts such asdeclare moduleblocks. -
#8817
652cfbbThanks @dyc3! - Fixed #8765: The HTML parser can now parse directive modifiers with a single colon, e.g.@keydown.:. -
#8704
a1914d4Thanks @Netail! - Added the nursery rulenoRootType.
Disallow the usage of specified root types. (e.g.mutationand/orsubscription)Invalid:
{ "options": { "disallow": ["mutation"] } }type Mutation { SetMessage(message: String): String }
-
#8712
251b47bThanks @Netail! - Renamed the following GraphQL nursery rules to match the Biome standard:useUniqueArgumentNames->noDuplicateArgumentNamesuseUniqueFieldDefinitionNames->noDuplicateFieldDefinitionNamesuseUniqueGraphqlOperationName->noDuplicateGraphqlOperationNameuseUniqueInputFieldNames->noDuplicateInputFieldNamesuseUniqueVariableNames->noDuplicateVariableNames
Run the
biome migrate --writecommand to automatically update the configuration file. -
#7602
957cd8eThanks @kedevked! - Added the nursery lint ruleuseErrorCause.This rule enforces that errors caught in a
catchclause are not rethrown without wrapping them in a newErrorobject and specifying the original error as thecause. This helps preserve the error’s stack trace and context for better debugging.It can be configured with the following option:
requireCatchParameter: (default:true)- When
true, the rule requires thatcatchclauses have a parameter. If athrowstatement appears inside acatchclause without a parameter, it will be flagged.
- When
Invalid examples:
try { foo(); } catch { throw new Error("fail"); }
try { foo(); } catch (err) { throw new Error(err.message); }
Valid examples:
try { foo(); } catch (err) { throw new Error("fail", { cause: err }); }
try { foo(); } catch (error) { throw new Error("Something went wrong", { cause: error }); }
Valid example when
requireCatchParameterisfalse:Valid:
try { foo(); } catch { throw new Error("fail"); }
-
#8725
95aba98Thanks @dyc3! - Fixed #8715: The CSS parser will now recover slightly better if a semicolon is missing from Tailwind's@applyat-rule. -
#8616
4ee3bdaThanks @Netail! - Added the nursery ruleuseLoneAnonymousOperation. Disallow anonymous operations when more than one operation specified in document.Invalid:
query { fieldA } query B { fieldB }
-
#8624
291c9f2Thanks @taga3s! - Added the nursery ruleuseInlineScriptIdto the Next.js domain.
This rule enforcesidattribute onnext/scriptcomponents with inline content ordangerouslySetInnerHTML.The following code is invalid:
import Script from "next/script"; export default function Page() { return ( <Script>{`console.log('Hello');`}</Script> // must have `id` attribute ); }
-
#8767
0d15370Thanks @mdevils! - Fixed #3512:
useExhaustiveDependenciesnow properly handles nested destructuring patterns
from hook results.const [[x, y], setXY] = useState([1, 2]); useEffect(() => { console.log(x, y); }, [x, y]); // x and y are now correctly recognized as unstable
-
#8757
17ed9d3Thanks @Netail! - Added the nursery rulenoDivRegex. Disallow equal signs explicitly at the beginning of regular expressions.Invalid:
var f = function () { return /=foo/; };
-
#8836
aab1d17Thanks @dyc3! - Fixed #7858: Biome now parses Astro files with empty frontmatter blocks. -
#8755
3a15c29Thanks @arturalkaim! - Fixed #6670. The$filenamemetavariable can now be used in GritQLwhereclauses to filter matches by filename. -
#8821
63e68a1Thanks @playhardgopro! - Fixed several bugs in Vue conditional rules (useVueValidVIf,useVueValidVElse, anduseVueValidVElseIf) related to whitespace handling, newlines, and self-closing tags. -
#8767
0d15370Thanks @mdevils! - Fixed #3685:
useExhaustiveDependenciesnow properly handles transparent expression
wrappers like non-null assertions and type assertions in dependency comparisons.useMemo(() => Boolean(myObj!.x), [myObj!.x]); // No longer reports incorrect diagnostics useMemo(() => myObj!.x?.y === true, [myObj!.x?.y]); // Now correctly matches dependencies
-
#8597 [
f764007](f7640071fa356808...
Biome CLI v2.3.11
2.3.11
Patch Changes
-
#8583
83be210Thanks @dyc3! - Added the new nursery ruleuseVueValidTemplateRoot.This rule validates only root-level
<template>elements in Vue single-file components. If the<template>has asrcattribute, it must be empty. Otherwise, it must contain content.Invalid examples:
<template src="./foo.html">content</template>
<template></template>
Valid examples:
<template>content</template>
<template src="./foo.html"></template>
-
#8586
df8fe06Thanks @dyc3! - Added a new nursery ruleuseVueConsistentVBindStyle. Enforces consistentv-bindstyle (:propshorthand vsv-bind:proplonghand). Default prefers shorthand; configurable via rule options. -
#8587
9a8c98dThanks @dyc3! - Added the ruleuseVueVForKey, which enforces that any element usingv-foralso specifies akey.Invalid
<li v-for="item in items">{{ item }}</li>
Valid
<li v-for="item in items" :key="item.id">{{ item }}</li>
-
#8586
df8fe06Thanks @dyc3! - Added a new nursery ruleuseVueConsistentVOnStyle. Enforces consistentv-onstyle (@eventshorthand vsv-on:eventlonghand). Default prefers shorthand; configurable via rule options. -
#8583
83be210Thanks @dyc3! - Added the new nursery ruleuseVueValidVOnce. Enforces that usages of thev-oncedirective in Vue.js SFC are valid.<!-- Valid --> <div v-once /> <!-- Invalid --> <div v-once:aaa /> <div v-once.bbb /> <div v-once="ccc" />
-
#8498
d80fa41Thanks @tt-a1i! - Fixed #8494. ExtendednoUndeclaredEnvVarsto support bracket notation (process.env["VAR"],import.meta.env["VAR"]), Bun runtime (Bun.env.VAR,Bun.env["VAR"]), and Deno runtime (Deno.env.get("VAR")). -
#8509
574a909Thanks @ematipico! - Added support for parsing and formatting the Svelte{#await}syntax, whenhtml.experimentalFullSupportEnabledis set totrue.-{#await promise then name } +{#await promise then name} -{:catch name} +{:catch name} {/await}
-
#8316
d64e92dThanks @washbin! - Added the new nursery rulenoMultiAssign. This rule helps to prevent multiple chained assignments.For example, the following code triggers because there are two assignment expressions in the same statement.
const a = (b = 0);
-
#8592
a5f59cdThanks @Netail! - Added the nursery ruleuseUniqueInputFieldNames. Require fields within an input object to be unique.Invalid:
query A($x: Int, $x: Int) { field }
-
#8524
17a6156Thanks @JacquesLeupin! - Fixed #8488: Relative plugin paths are now resolved from the configuration file directory, including when configurations are merged (e.g.extends: "//"). -
#8655
3260ec9Thanks @JacquesLeupin! - Fixed #8636: Biome's CSS formatter now breaks comma-separated declaration values at top-level commas when wrapping. -
#8537
cc3e851Thanks @dibashthapa! - Fixed #8491: Resolved false positive errors for safe boolean expressions. There are still pending fixes. Head to #8491 (comment) for more detailsThis new change will check for safe boolean expressions in variable declarations.
For example,
Valid:
let isOne = 1; let isPositiveNumber = number > 0; return ( <div> {" "} {isOne && "One"} {isPositiveNumber && "Is positive"} </div> );
Invalid:
let emptyStr = ""; let isZero = 0; return ( <div> {emptyStr && "Empty String"} {isZero && "Number is zero"}{" "} </div> );
-
#8511
16a9036Thanks @ematipico! - Improved the diagnostics of the rulesuseSortedClassesandnoUnnecessaryConditions. The diagnostics now state that these rules are a work in progress and link to the relevant GitHub issue. -
#8521
a704be9Thanks @ToBinio! - Added the nursery ruleuseVueConsistentDefinePropsDeclaration, which enforces consistentdefinePropsdeclaration style.Invalid
<script setup lang="ts"> const props = defineProps({ kind: { type: String }, }); </script>
Valid
<script setup lang="ts"> const props = defineProps<{ kind: string; }>(); </script>
-
#8595
7c85bf0Thanks @dyc3! - Fixed #8584: The HTML formatter will preserve whitespace after some elements and embedded expressions, which more closely aligns with Prettier's behavior.- <h1>Hello, {framework}and Svelte!</h1> + <h1>Hello, {framework} and Svelte!</h1>
-
#8598
5e85d43Thanks @Netail! - Added the nursery ruleuseUniqueFieldDefinitionNames. Require all fields of a type to be unique.Invalid:
type SomeObject { foo: String foo: String }
-
#8495
b573d14Thanks @taga3s! - Fixed #8405:noMisusedPromisesnow emits warnings/errors when a function returns union types such asT | Promise<T>which is used in conditionals.const a = (): boolean | Promise<boolean> => Promise.resolve(true); if (a()) { } // Now correctly flagged
-
#8632
0be7d12Thanks @Bertie690! - The documentation & rule sources forlint/complexity/noBannedTypeshave been updated to fix a few oversights.In addition to some general typo fixes:
-
The rule now recommends
Record<keyof any, never>instead ofRecord<string, never>(the latter of which incorrectly allows symbol-keyed properties). -
The rule mentions an alternate method to enforce object emptiness involving
unique symbol-based guards used bytype-festand many other packages:declare const mySym: unique symbol; // Since this type's only property is an unexpor...
-