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
f764007Thanks @Netail! - Added the nursery rulenoDuplicateEnumValueNames. Enforce unique enum value names.Invalid:
enum A { TEST TesT }
-
#8679
33dfd7cThanks @ematipico! - Fixed #8678. Now Biome correctly parses components inside Vue, Svelte and Astro files when they have the same name of self-closing elements. -
#8617
31a9bfeThanks @Netail! - Added the nursery ruleuseLoneExecutableDefinition. Require queries, mutations, subscriptions or fragments to be located in separate files.Invalid:
query Foo { id } fragment Bar on Baz { id }
-
#8697
8519669Thanks @Faizanq! - Added the nursery lint rulenoExcessiveLinesPerFileto CSS and GraphQL. -
#8711
365f7aaThanks @Netail! - Added new nursery rulenoDuplicateEnumValues, which disallows defining an enum with multiple members initialized to the same value. -
#8767
0d15370Thanks @mdevils! - Fixed #5914:
useExhaustiveDependenciesnow properly handles variables declared in the same
statement.const varA = Math.random(), varB = useMemo(() => varA, [varA]); // varA is now correctly recognized as needed
-
#8767
0d15370Thanks @mdevils! - Fixed #8427:
useExhaustiveDependenciesnow properly resolves variable references to detect
captured dependencies.const fe = fetchEntity; useEffect(() => { fe(id); }, [id, fe]); // fe is now correctly detected as needed
-
#8767
0d15370Thanks @mdevils! - Fixed #8484:
useExhaustiveDependenciesnow properly handles member access on stable hook
results.const stableObj = useStable(); useMemo(() => { return stableObj.stableValue; // stableObj.stableValue is now correctly recognized as stable }, []);
-
#8767
0d15370Thanks @mdevils! - Fixed #7982:
useExhaustiveDependenciesnow properly handles callback expressions with type
assertions.const callback = useCallback( (() => { return count * 2; }) as Function, [count], // count is now correctly detected );
-
#8766
39eb545Thanks @Netail! - Fixed #8761: Reverted wrapping the URL of rule descriptions with<>, causing broken URLs in VSCode. -
#8767
0d15370Thanks @mdevils! - Fixed #3080:
useExhaustiveDependenciesnow properly analyzes captures within referenced
functions passed to hooks.function myEffect() { console.log(foo, bar); } useEffect(myEffect, [foo, bar]); // foo and bar are now correctly detected
-
#8740
4962ed0Thanks @Netail! - Extra rule source references.biome migrate eslintshould do a bit better detecting rules in your eslint configurations. -
#8776
395746fThanks @codiini! - Fixed #6003:noUselessUndefinedInitializationno longer reports exported variables initialized toundefined. In Svelte 4, this pattern is used to declare optional component props. -
#8767
0d15370Thanks @mdevils! - Fixed #4248:
useExhaustiveDependenciesnow correctly handles function props passed as
callbacks.const data = React.useMemo(getData, [getData]); // getData is now correctly recognized as needed
-
#8819
bc191ffThanks @Netail! - Fixed #6567:
noUnknownPropertynow ignores unknown properties in at-rules which support descriptors. -
#8787
adb652fThanks @tuyuritio! - Fixed #8777: Add support for:active-view-transitionpseudo-class. -
#8639
6577e32Thanks @ohnoah! - Added the nursery lint rulenoExcessiveLinesPerFile.
Biome now reports files that exceed a configurable line limit.// maxLines: 2 const a = 1; const b = 2; const c = 3;
-
#8753
71b5c6eThanks @Netail! - Added the nursery rulenoExcessiveClassesPerFile. Enforce a maximum number of classes per file.Invalid:
class Foo {} class Bar {}
-
#8754
d6b2bdaThanks @Netail! - Added the nursery rulenoFloatingClasses. Disallownewoperators outside of assignments or comparisons.Invalid:
new Date();
What's Changed
- feat(graphql_analyze): implement useUniqueEnumValueNames by @Netail in #8597
- chore(github): update issue templates by @DayKev in #8668
- feat(graphql_analyze): implement useLoneExecutableDefinition by @Netail in #8617
- chore: remove old unused options by @Netail in #8676
- feat(biome_js_analyze): implement noExcessiveLinesPerFile by @ohnoah in #8639
- chore(deps): update github-actions by @renovate[bot] in #8684
- chore(deps): update dependency tombi to v0.7.14 by @renovate[bot] in #8683
- fix(html/parser): parsing of components by @ematipico in #8679
- chore(deps): update rust crate libc to 0.2.179 by @renovate[bot] in #8686
- fix(deps): update rust crate libc to 0.2.179 by @renovate[bot] in #8688
- chore(deps): update dependency dprint to v0.51.1 by @renovate[bot] in #8689
- chore(deps): update taiki-e/install-action action to v2.65.13 by @renovate[bot] in #8687
- feat: add useErrorCause Rule by @kedevked in #7602
- fix(lint): noUnusedVariables should ignore type parameters in ambient context by @wataryooou in #8561
- chore: add css, graphql & html new assist rule tasks by @Netail in #8703
- feat(analyze/html): add noDuplicateAttributes by @dyc3 in #8653
- feat(graphql_analyze): implement noRootType by @Netail in #8704
- chore: rename GraphQL nursery rules by @Netail in #8712
- docs: fix 'instaiated' typo in no-invalid-builtin-instantiation by @JoshuaKGoldberg in #8716
- feat(js_analyze): implement noDuplicateEnumValues by @Netail in #8711
- fix(parse/css): slightly better recovery for
@applyby @dyc3 in #8725 - chore: extra rule sources by @Netail in #8740
- chore(deps): update rust crate jiff to 0.2.18 by @renovate[bot] in #8745
- chore(deps): update dependency tombi to v0.7.16 by @renovate[bot] in #8744
- chore(deps): update rust crate proc-macro2 to 1.0.105 by @renovate[bot] in #8747
- chore(deps): update rust crate serde_json to 1.0.149 by @renovate[bot] in #8749
- chore(deps): update rust crate quote to 1.0.43 by @renovate[bot] in #8748
- chore(deps): update rust crate libc to 0.2.180 by @renovate[bot] in #8746
- chore(deps): update github-actions by @renovate[bot] in #8743
- chore(deps): update rust crate url to 2.5.8 by @renovate[bot] in #8750
- chore(deps): update pnpm to v10.27.0 by @renovate[bot] in #8752
- fix(deps): update rust crates by @renovate[bot] in #8751
- fix(grit): make $filename metavariable accessible in GritQL plugins by @arturalkaim in #8755
- fix(biome_configuration): revert URL brackets by @Netail in #8766
- fix(linter):
useExhaustiveDependenciesmultiple fixes (fixes #3080, fixes #4248, fixes #5914, fixes #8427, fixes #8484, fixes #3685, fixes #3512, fixes #7982) by @mdevils in #8767 - feat(lint): add noVueOptionsApi rule by @BaeSeokJae in #8648
- feat(biome_js_analyze): port
useInlineScriptIdfrom Next.js by @taga3s in #8624 - docs: fix typo inside
biome_analyze/CONTRIBUTING.mdby @Bertie690 in #8781 - ci: sanity check to make sure wasm artifact exists by @dyc3 in #8784
- feat(js_analyze): implement noDivRegex by @Netail in #8757
- fix(linter): add support for active-view-transition pseudo-class by @tuyuritio in #8787
- fix(justfile): remove errant
runargument from test commands by @jfmcdowell in #8789 - feat(js_analyze): implement noFloatingClasses by @Netail in #8754
- feat(js_analyze): implement noExcessiveClassesPerFile by @Netail in #8753
- chore(deps): update rust:1.92.0-bookworm docker digest to e90e846 by @renovate[bot] in #8791
- chore(deps): update rust:1.92.0-bullseye docker digest to c6d501c by @renovate[bot] in #8792
- chore(deps): update dependency tombi to v0.7.19 by @renovate[bot] in #8795
- chore(deps): update dependency @types/node to v24.10.9 by @renovate[bot] in #8794
- chore(deps): update rust crate bpaf to 0.9.22 by @renovate[bot] in #8796
- chore(deps): update rust crate tower to 0.5.3 by @renovate[bot] in #8797
- fix(deps): update @biomejs packages by @renovate[bot] in #8798
- chore(deps): update github-actions by @renovate[bot] in #8799
- chore(deps): update rust crate indexmap to 2.13.0 by @renovate[bot] in #8801
- chore(deps): update pnpm to v10.28.0 by @renovate[bot] in #8800
- fix(linter): noUselessUndefinedInitialization false positive in svelte 4. by @codiini in #8776
- feat(html): add various helpers to html syntax nodes by @dyc3 in #8804
- fix(grit): correct
arrow_functionslot indices for GritQL patterns by @TheBaconWizard in #8793 - feat(linter): add noExcessiveLinesPerFile to CSS and GraphQL by @Faizanq in #8697
- docs(organizeImports): add a note for full import merging by @Conaclos in #8811
- docs(organizeImports): fix note about import merging by @Conaclos in #8813
- feat(dx): add prettier-compare tool by @dyc3 in #8805
- feat(graphql_analyze): implement useLoneAnonymousOperation by @Netail in #8616
- fix(parse/html/vue): accept colon modifier in vue directives by @dyc3 in #8817
- fix(linter): reduce
noSecretsfalse positives on CamelCase identifiers by @Exudev in #8832 - feat(prettier-compare): support astro by @dyc3 in #8835
- fix(parse/html/astro): accept astro files with empty frontmatter by @dyc3 in #8836
- fix(css_analyze): ignore at-rules supporting descriptors by @Netail in #8819
- chore: ignore
prettier-comparepkg by @ematipico in #8843 - chore: update sponsors by @ematipico in #8844
- fix(lint): handle newlines in useVueValidVElse and useVueValidVElseIf by @playhardgopro in #8821
- ci: release by @github-actions[bot] in #8671
New Contributors
- @DayKev made their first contribution in #8668
- @ohnoah made their first contribution in #8639
- @wataryooou made their first contribution in #8561
- @JoshuaKGoldberg made their first contribution in #8716
- @arturalkaim made their first contribution in #8755
- @BaeSeokJae made their first contribution in #8648
- @tuyuritio made their first contribution in #8787
- @codiini made their first contribution in #8776
- @TheBaconWizard made their first contribution in #8793
- @Faizanq made their first contribution in #8697
- @Exudev made their first contribution in #8832
- @playhardgopro made their first contribution in #8821
Full Changelog: https://github.com/biomejs/biome/compare/@biomejs/biome@2.3.11...@biomejs/biome@2.3.12