All versions since 2.6.3
2.6.3
Patch Changes
-
#12275
807e616Thanks @dyc3! - Added the new nursery rulenoArraySortForMinMax, which reports sorting an array only to read its smallest or largest value. UseMath.min()orMath.max()instead.const minimum = array.toSorted((a, b) => a - b)[0]; -
#12432
cf61682Thanks @dyc3! - Added the nursery rulenoBooleanSortComparator, which reports sort comparators that return a boolean instead of a number. For example,array.sort((a, b) => a > b)never puts the first item before the second, so the array isn’t sorted correctly. -
#12304
b4654c5Thanks @dyc3! - Added the new nursery rulenoEagerArrayMethodsInLoops, which reports.map()and.filter()calls in the header offor...ofloops. These calls build a new array that is only used by the loop.for (const name of users.map((user) => user.name)) {console.log(name);} -
#12121
66c3791Thanks @dyc3! - Added the nursery rulenoNewRequire, which disallows callingrequirewithnew, such asnew require("app-header"). -
#12316
34b520dThanks @dyc3! - Added the new nursery rulenoObsoleteAttributes, which disallows obsolete attributes on HTML elements and suggests what to use instead.<table bgcolor="#ffffff" cellpadding="5"></table> -
#12258
cce2385Thanks @dyc3! - Added the nursery rulenoPathConcat, which disallows building file paths and URLs by joining strings to__dirname,__filename,import.meta.dirname,import.meta.filename, orimport.meta.url.const fullPath = __dirname + "/foo.js"; // reported -
#12287
e12ad78Thanks @dyc3! - Added the new nursery rulenoPlaywrightNthMethods, which disallows selecting Playwright elements by position withfirst(),last(), andnth(). A test that relies on the position of an element can act on a different element when the page changes.await page.locator("button").first().click(); -
#12343
62ad123Thanks @vibbix! - Added the nursery rulenoSelfNestedLayer, which disallows nesting a cascade layer inside a layer with the same name. Layer names inside an@layerblock are relative to it, so the inner layer below creates the sublayercomponents.componentsinstead of adding tocomponents.@layer components {@layer components {.button {color: red;}}} -
#12289
bbbd95dThanks @dyc3! - Added the nursery rulenoShortTimeValues, which reports CSS animation and transition times that are shorter than the configuredminimumnumber of milliseconds. The rule does nothing untilminimumis set.For example, the following code is invalid when
minimumis100:a {transition-duration: 80ms;} -
#12431
f748ec0Thanks @dyc3! - Added the nursery rulenoSvelteInternal, which disallows importing fromsvelte/internaland its submodules. These modules are private to Svelte and can change or disappear in any release.import { get_current_component } from "svelte/internal"; -
#12270
8ae35c4Thanks @dyc3! - Added the nursery rulenoTanstackQueryRestDestructuring, which disallows rest destructuring and object spread on TanStack Query results. Both read every property of the result, so the component updates on every change to the query.import { useQuery } from "@tanstack/react-query";const { data, ...rest } = useQuery({ queryKey: ["todos"], queryFn: fetchTodos });The rule belongs to the new
tanstackQuerydomain. -
#12308
372af2aThanks @dyc3! - Added the new nursery rulenoUnreadableForOfExpression, which reportsfor...ofandfor await...ofloops that go through the result of a complex expression instead of a variable, a property, or a short call.for (const item of getItems(createArgument(seed))) {} // reported -
#12422
0be8d10Thanks @dyc3! - Added the new nursery rulenoUnsafeReturn, which disallows returning a value typed asanyfrom a function.function parse(text: string) {return JSON.parse(text); // reported} -
#12311
8434c92Thanks @dyc3! - Added the nursery rulenoUselessSplice, which reportssplice()calls that have a simpler alternative. For example,array.splice(0, 1)can be written asarray.shift(). -
#12293
eaa4a2bThanks @dyc3! - Added the nursery rulenoVueUnusedEmitDeclarations, which reports events that a Vue component declares but never emits.For example, the following component never emits
close:<script setup>const emit = defineEmits(["change", "close"]);emit("change");</script> -
#12386
f01ebb0Thanks @dyc3! - Added the nursery rulenoVueVTextVHtmlOnComponent, which disallowsv-textandv-htmlon Vue components. These directives replace everything inside the component’s root element instead of filling its slot.<template><MyComponent v-html="html"></MyComponent></template> -
#12385
7bd38b7Thanks @dyc3! - Added the new nursery rulenoVueWatchAfterAwait, which disallows creating watchers after anawaitin a Vue component’ssetup()function. Vue doesn’t stop these watchers when the component is removed. A watcher is allowed when the function it returns is stored, so that function can be called later to stop the watcher.<script>import { watch } from "vue";export default {async setup() {await fetchUser();watch(source, () => {});},};</script> -
#12286
50d2a4eThanks @dyc3! - Added the nursery rulenoZeroLengthUnit, which disallows units on zero lengths in CSS. Biome can remove the unit.a {top: 0px;} -
#12300
ab2eb9eThanks @dyc3! - Added the nursery ruleuseBlockStatementOverIife, which reports functions that are called immediately when a block statement can replace them. Biome can replace these functions with a block statement.Invalid:
(() => {const value = getValue();run(value);})(); -
#12421
1c2cac0Thanks @dyc3! - Added the nursery ruleuseConsistentLightnessNotation, which enforces writing the lightness oflab(),lch(),oklab(), andoklch()colors as a percentage, or as a number with thenotationoption. For example, with the default options,oklch(0.85 0.17 88)is reported and can be fixed tooklch(85% 0.17 88). -
#12224
fef7ed4Thanks @dyc3! - Added the nursery ruleuseExpectToContain, which reports tests that compare the result ofincludes()to a boolean, and suggests usingtoContain()instead.expect(fruits.includes("apple")).toBe(true); -
#12299
0d5025dThanks @dyc3! - Added the new nursery ruleuseIteratorZip, which reportsforloops that use an index only to read the same position from several arrays. Such loops can useIterator.zip()instead.// reportedfor (let index = 0; index < Math.min(names.length, scores.length); index++) {save(names[index], scores[index]);} -
#12298
a234d2fThanks @dyc3! - Added the nursery ruleuseMathAbs, which reports manual absolute value calculations and range checks that can useMath.abs(). For example,value < 0 ? -value : valuecan be written asMath.abs(value), andvalue > limit || value < -limitcan be written asMath.abs(value) > limit. -
#12499
bd024ccThanks @dyc3! - Added the nursery ruleuseMathTrunc, which requiresMath.trunc()instead of bitwise operations orparseInt(String(x), 10)for removing the decimal part of a number. For example,const result = value | 0;andconst result = ~~value;are now reported. -
#12314
9e875a4Thanks @dyc3! - Added the new nursery ruleusePackageJsonValidCpu, which reports acpufield inpackage.jsonthat isn’t an array of known processor types. Thecpufield lists the processor types that the package supports.For example, the rule reports the following
package.jsonfile becausex86isn’t a processor type that package managers recognize:{"name": "my-package","cpu": ["x86"]} -
#12315
cb30544Thanks @dyc3! - Added the nursery ruleusePackageJsonValidEngines, which reports an invalidenginesfield inpackage.json. The field must be an object, and each of its values must be a non-empty string.For example, the following
enginesfield is reported because the version ofnodeis a number:{"engines": {"node": 24}} -
#12400
407604dThanks @dyc3! - Added the nursery ruleuseVueComponentIs, which requires Vue<component>elements to bind theisattribute with:isorv-bind:is. Without it, Vue has no component to render.<template><component :is="currentView" /></template> -
#12337
c371520Thanks @dyc3! - Added the nursery ruleuseVueToggleInsideTransition, which requires the element inside a Vue<Transition>to be shown and hidden withv-iforv-show. Without one of them, the element is always shown and the transition never plays.<template><Transition><div>Content</div></Transition></template> -
#12387
64472e9Thanks @dyc3! - Added the nursery ruleuseVueTypedRef, which reportsref()andshallowRef()calls in TypeScript that have no type argument and no initial value other thannullorundefined. Without a type, TypeScript can’t tell which values these refs are meant to hold.import { ref } from "vue";const count = ref(); -
#12423
bf1a55aThanks @dyc3! - Added the nursery ruleuseVueVOnExact, which requires the.exactmodifier on av-onlistener when another listener for the same event on the element needs more modifier keys, such as.ctrl. Without.exact, both listeners run when those keys are held down. The rule accepts the following code:<template><button @click.exact="select" @click.ctrl="open"></button></template> -
#12418
208730eThanks @latin-1! - Fixed #12417:useSortedPropertiescould produce invalid CSS when sorting properties without a final semicolon. Comments attached to reordered properties are preserved. -
#12216
f2a3c71Thanks @dyc3! - Added the new nursery rulenoDanglingUnderscore, which disallows variable names, function names, and property accesses that start or end with an underscore.const _count = 0; // reporteduser._id; // reported -
#12536
438997fThanks @vidigoat! - Fixed the formatter removing the parentheses around an instantiation expression before+,-,<,>,>=,>>and>>>. TypeScript readsmake<T> + yasmake < T > +y, andmake<T> >> ydoesn’t parse.x = make<T> + y;x = (make<T>) + y;x = make<T> >> y;x = (make<T>) >> y; -
#12540
7d3e8a1Thanks @vidigoat! - Fixed the formatter removing the parentheses around an instantiation expression before a non-null assertion or type arguments of a class heritage, which produced code that doesn’t parse.const a = make<T>!;const a = (make<T>)!;class D extends B<T><T> {}class D extends (B<T>)<T> {} -
#12496
09d89b9Thanks @vidigoat! - Fixed the formatter removing the parentheses around binary, logical, type-cast and instantiation operands of an instantiation expression. The type arguments then applied to the last operand only, and a nested instantiation expression didn’t parse.const x = a + b<T>;const x = (a + b)<T>;const y = a as B<T>;const y = (a as B)<T>;const z = f<A><B>;const z = (f<A>)<B>; -
#12526
dbcdab1Thanks @dyc3! - Fixed #12524: the Markdown formatter no longer removes the blank line between a paragraph and the list that follows it. Removing it could change the document, because an ordered list that doesn’t start at1can’t interrupt a paragraph and became part of the paragraph text.Steps:3. three4. four -
#12509
470018bThanks @dyc3! - Fixed #12507: the Markdown formatter no longer drops the>markers after an empty quote line whenproseWrapis"always"or"never". Previously, the text after the empty line was moved out of the blockquote.> a>b> b -
#12598
5699601Thanks @vidigoat! - Fixed the formatter removing the parentheses around the callee of anewexpression when it contains a dynamicimport()call, which produced code that doesn’t parse.new import("foo").bar();new (import("foo").bar)(); -
#12508
87d9e6bThanks @dyc3! - Fixed #12502:noInvalidGridAreasnow counts the cells in each row ofgrid-template-areasinstead of comparing the length of the row text. Rows such as"a" "bb"are no longer reported, and rows such as"abc" "d e"are now reported. -
#12530
7f467b2Thanks @dyc3! - Fixed #12529:noUselessElseno longer reports anelseclause when theifblock ends with aswitchstatement that has nodefaultclause. If no case matches, such aswitchdoesn’t exit, so theelseclause is needed. -
#12511
d4ea663Thanks @dyc3! - Fixed #12505:useDomNodeTextContentno longer reportsinnerTexton values whose type annotation shows they aren’t DOM nodes. The following code is now valid:const Link = ({ innerText }: { innerText: string }) => <a>{innerText}</a>; -
#12588
e262362Thanks @ematipico! - FixednoDescendingSpecificityto compare resolved nested selector targets. Biome no longer reports nested selectors that resolve to different targets, detects equivalent explicit and nested targets, and emits one diagnostic when a parent selector list expands the same nested selector multiple times.For example, the following selectors are no longer reported because their final targets are
.columnandcode, respectively:.card {.column {:root[data-theme="dark"] & {}}code {:root[data-theme="dark"] & {}}} -
#12534
e59a324Thanks @Netail! - Improved the diagnostics ofnoIdenticalTestTitle. Biome now reports one diagnostic per repeated title, pointing at the first occurrence and at every later occurrence, instead of one diagnostic per duplicate. -
#12528
a3132dcThanks @ff1451! - Fixed #12503:noUnknownPropertynow checks SCSS nested properties by the name Sass emits for them. For example,radiusinborder: { radius: 4px; }is checked asborder-radiusand is no longer reported, whilecolorinfont: { color: red; }is checked asfont-colorand is now reported. -
#12113
ec4eb2dThanks @dyc3! - Added the nursery ruleuseConsistentUnicodeBom, which disallows a leading Unicode byte order mark by default and can require one withbom: "always". The rule supports JavaScript, TypeScript, JSON, CSS, GraphQL, HTML, and Markdown, provides a fix, and preserves theunicode-bomoption during ESLint migration.The following example is invalid by default because it starts with an invisible U+FEFF character:
const value = 1; -
#12248
afbc81eThanks @dyc3! - Added the nursery ruleuseReactNativeValidPlatformColors, which requiresPlatformColor()andDynamicColorIOS()calls to use values written directly in the call, so React Native can optimize them.import { PlatformColor } from "react-native";const labelColor = "labelColor";const color = PlatformColor(labelColor); -
#12599
b62494aThanks @dyc3! - Fixed #12532: checking the project root no longer appliesfiles.includesexclusions to directories above the project. -
#12578
6162922Thanks @ematipico! - Fixed GraphQL parsing and formatting for executable descriptions and legacy fragment variables. Biome now formats inputs such as"Description" query { field }without panicking and removes insignificant commas consistently. -
#12593
35c69adThanks @dyc3! - Fixed #12555: the default reporter now prints the command summary, the--max-diagnosticswarning, and the skipped-fixes notice to stderr instead of stdout. Diagnostics already go to stderr, so the summary can no longer get mixed into the middle of a diagnostic when a tool reads the two streams separately. -
#12415
9520907Thanks @latin-1! - Fixed #12412:useSortedPropertiesnow sorts properties inside@keyframesanimations in CSS and SCSS.
2.6.4
Patch Changes
-
#12261
19fbfb2Thanks @dyc3! - Added the new nursery rulenoConsoleSpaces, which reports a leading or trailing space in aconsole.log(),console.debug(),console.info(),console.warn(), orconsole.error()argument that sits next to another argument. These methods already put a space between arguments, so such a space prints twice.console.log("abc ", "def"); -
#12469
cd716d3Thanks @dyc3! - Added the new nursery rulenoMagicArrayFlatDepth, which reports number literals other than1passed as the depth ofArray.prototype.flat()unless a comment inside the parentheses explains them.const items = array.flat(2); -
#12470
92c9e81Thanks @dyc3! - Added the nursery rulenoNull, which reports uses of thenullliteral and suggestsundefinedinstead. Strict comparisons such asfoo === nullare allowed.let foo = null; -
#12483
9bd3527Thanks @dyc3! - Added the nursery rulenoReturnArrayPush, which reports code that uses the return value ofpush()orunshift(). These methods return the new length of the array, not the added item or the array.function add(item) {return items.push(item);} -
#12477
a384892Thanks @dyc3! - Added the nursery rulenoUnreadableIife, which reports arrow functions that are called right where they are defined and whose body is wrapped in parentheses.const foo = (bar => (bar ? bar.baz : baz))(getBar()); -
#12447
0a963e4Thanks @dyc3! - Added the nursery rulenoUselessRecursion, which reports functions that return a call to themselves when a loop can do the same work. Too many nested calls can crash the program with a stack overflow error.function findRoot(node) {if (node.parent) {return findRoot(node.parent);}return node;} -
#12554
2eddda9Thanks @dyc3! - Added the nursery rulenoVueComputedPropertiesInData, which reports computed properties used inside thedatafunction of a Vue component. Vue runsdatabefore it sets up computed properties, so the value read there isundefined.<script>export default {data() {return { total: this.doubled };},computed: {doubled() {return 2;},},};</script> -
#12586
824df15Thanks @dyc3! - Added the nursery rulenoVueDeprecatedDeleteSet, which reports calls to the$setand$deletefunctions,Vue.setandVue.delete, andsetanddelimported fromvue. Vue 3 removed these functions, so calling them throws an error.<script>export default {mounted() {this.$set(this.user, "name", "Alice");},};</script> -
#12648
6fc1a51Thanks @dyc3! - Added the nursery rulenoVueDeprecatedRouterLinkTagProp, which disallows thetagprop onRouterLink. Vue Router 4 ignores this prop, so the link still renders as an<a>element.<template><RouterLink tag="li" to="/">Home</RouterLink></template> -
#12631
de1188fThanks @dyc3! - Added the new nursery rulenoVueDeprecatedScopeAttribute, which reports thescopeattribute on<template>elements in Vue files. Vue no longer supports this attribute, so usev-slotto receive slot props instead.<template><ListComponent><template scope="props">{{ props.title }}</template></ListComponent></template> -
#12562
5d7553bThanks @dyc3! - Added the new nursery rulenoVueMultipleSlotArgs, which disallows passing more than one argument to a Vue slot from a render function. Slot content written in a template receives only the first argument.<script>export default {render() {return this.$slots.default(item, index); // reported},};</script> -
#12513
2e520d8Thanks @dyc3! - Added the nursery rulenoVueMutatingProps, which reports code that changes the props of a Vue component, in the script or in the template. Props belong to the parent component, so the child should emit an event or copy the value instead.<script setup>const props = defineProps({ items: Array });props.items.push("new item");</script> -
#12567
144b786Thanks @dyc3! - Added the nursery rulenoVueSideEffectsInComputed, which reports Vue computed properties that change state. Vue decides when to run a computed property, so changes made inside one happen at unpredictable times.<script setup>import { computed, ref } from "vue";const items = ref([]);// `reverse()` changes `items.value` in place.const reversedItems = computed(() => items.value.reverse());</script> -
#12603
861b288Thanks @dyc3! - Added the new nursery rulenoVueUnusedRefs, which reports template refs in Vue components that nothing reads through$refs,useTemplateRef(), or a variable of the same name in<script setup>. The rule needshtml.experimentalFullSupportEnabledto betrue.<template><input ref="input" /></template> -
#12285
68770e0Thanks @dyc3! - Added the new nursery rulenoYamlBooleanKeys, which disallows boolean values as keys in YAML. For example, the following key is a boolean instead of text, so it is reported:true: enabled -
#12338
f46411bThanks @dyc3! - Added the nursery ruleuseSvelteEventDispatcherTypes, which reportscreateEventDispatcher()calls that don’t declare the types of their events in Svelte components written in TypeScript.The rule accepts a call that declares its events:
<script lang="ts">import { createEventDispatcher } from "svelte";const dispatch = createEventDispatcher<{ save: string }>();</script> -
#12615
ade9845Thanks @dyc3! - Added the nursery ruleuseVueDefineOptions, which reports the default export of a plain<script>block in Vue components that also use<script setup>, and suggests setting those options withdefineOptions()instead.<script>export default { name: "MyComponent" }; // reported</script><script setup>const props = defineProps(["title"]);</script> -
#12514
e74b4dcThanks @dyc3! - Added the nursery ruleuseVueDefinePropsDestructuring, which requires destructuring the props returned bydefineProps()in Vue<script setup>blocks. It also reportswithDefaults(), because destructured props can set their default values directly.<script setup lang="ts">const props = defineProps<{ foo?: string }>();</script> -
#12559
94985baThanks @dyc3! - Added the nursery ruleuseVueTemplateRef, which requiresuseTemplateRef()instead ofref()orshallowRef()to access elements of the template in<script setup>.<template><input ref="input" /></template><script setup>import { ref } from "vue";const input = ref(); // reported</script> -
#12512
6be5078Thanks @dyc3! - Added the nursery ruleuseVueTypedProps, which reports Vue props declared without a type, in thepropsoption,defineProps(), ordefineModel(). Without a type, Vue accepts any value for the prop and can’t warn when a component receives the wrong kind of value.<script setup>defineProps(["title"]);</script> -
#12653
f307633Thanks @dyc3! - Added the nursery ruleuseVueVModel, which reports a prop binding on a Vue component paired with anupdate:listener that only writes the new value back, and suggestsv-modelinstead.<template><MyComponent :title="title" @update:title="title = $event" /></template> -
#12591
a810209Thanks @dyc3! - Added the nursery ruleuseVueValidDefineEmits, which enforces valid usage of Vue’sdefineEmitsmacro in<script setup>.For example, the following code is now reported, because
defineEmitsdeclares its events with both a type and an argument:<script setup lang="ts">const emit = defineEmits<(e: "notify") => void>(["submit"]);</script> -
#12614
9308110Thanks @dyc3! - Added the nursery ruleuseVueValidDefineProps, which reportsdefineProps()calls that Vue can’t compile or that declare props incorrectly. For example, it reports a component that callsdefineProps()twice, or whosedefineProps()argument uses a variable declared in<script setup>:<script setup>const definition = { msg: String };defineProps(definition);</script> -
#12570
222a230Thanks @dyc3! - Added the nursery ruleuseVueValidVIs, which reportsv-isdirectives that have an argument or modifiers, have no value, or are used on a component instead of a native HTML element.For example, the following
v-isdirective has no value:<template><tr v-is></tr></template> -
#12521
4010bb7Thanks @dyc3! - Added the nursery ruleuseVueValidVMemo, which reports invalidv-memodirectives in Vue templates. Av-memodirective must have an array value, can’t have an argument or modifiers, and doesn’t work inside an element withv-for.For example, the following value is an object instead of an array:
<template><div v-memo="{ id }"></div></template> -
#12597
aff42a7Thanks @dyc3! - Added the nursery ruleuseVueValidVModel, which reportsv-modeldirectives that Vue can’t use: on unsupported elements or file inputs, with an argument or unknown modifier on a native element, without a value, or with a value that can’t be assigned to.For example, the following
v-modeldirectives are invalid:<template><div v-model="foo"></div><input v-model="foo + bar" /></template> -
#12569
3058597Thanks @dyc3! - Added the new nursery ruleuseVueValidVShow, which reportsv-showdirectives that have an argument, a modifier, or no value, or that are placed on a<template>element.<template v-show="isVisible"><div></div></template> -
#12525
e2e5a36Thanks @dyc3! - Added the nursery ruleuseVueValidVSlot, which reports misplaced, duplicated, or malformedv-slotdirectives in Vue templates.For example, the rule reports two
<template>elements that fill the same slot:<MyComponent><template #header>First title</template><template #header>Second title</template></MyComponent> -
#12472
efd16bdThanks @dyc3! - Added the new nursery ruleuseWhileLoopCondition, which reports loops such aswhile (true)andfor (;;)that start with anifstatement containing only abreak, and moves that condition into thewhilestatement.while (true) {if (!hasMore()) {break;} // reportedprocessNext();} -
#12640
167bb00Thanks @latin-1! - UpdateduseSortedPropertiesto followstylelint-config-recess-order7.9.0, adding sorting support forscroll-behavior, anchor positioning, multi-column layout, and other properties known to Biome. -
#12719
40a82b0Thanks @dyc3! - Improved the performance of the linter. Biome now spends less time setting up the enabled rules for each file it analyzes. -
#12722
f074730Thanks @dyc3! - Improved the performance ofbiome lintby about 1% to 3% on large projects, most noticeably with Biome’s default rules and with rules that track variables or unreachable code. -
#12501
90a4d74Thanks @ematipico! - Fixed #12466: the Biome daemon used more memory with everybiome check --use-serverrun. The daemon now reuses the data that it stores for each file and project, and it keeps syntax trees only for the files that it read most recently. -
#12501
90a4d74Thanks @ematipico! - Fixed biomejs/biome-vscode#923: when a file open in the editor changed on disk, the language server replaced the editor’s text with the text on disk. Biome now keeps the editor’s text of open files until they are closed, so diagnostics, code actions and formatting stay at the right positions. -
#12652
59ff42aThanks @kurovskyiii! - Fixed #12651: an imported name that the other module exports as both a type and a value now resolves to the type in type annotations, sonoBaseToStringno longer reportsslugbelow as an object.rule-slug.ts export type RuleSlug = string;export const RuleSlug = { create: (text: string): RuleSlug => text } as const;// main.tsimport { RuleSlug } from "./rule-slug";export const label = (slug: RuleSlug): string => `rule ${slug}`; -
#12678
301402fThanks @nhedger! - Fixed biomejs/biome-vscode#1113: the language server now shows a warning when the configuration file can’t be parsed. Previously, Biome stopped processing files without telling the user why. -
#12662
8c836ebThanks @dyc3! - Fixed #12645: the Markdown formatter no longer removes the blank line between a blockquote and the list that follows it, matching Prettier.> A note.- one- two -
#12662
8c836ebThanks @dyc3! - Fixed #12663: the Markdown formatter no longer removes the blank line between a table and the list that follows it, matching Prettier.| Table || ----- || Value |- Hello -
#12576
735d370Thanks @jfmcdowell! - Fixed #12541: Markdown list items whose markers are indented 4 or more spaces now nest at the correct level. Previously the formatter could move such an item under the item before it, or join it to that item’s text.1. Step- a- x- y- b- y- b -
#12575
0da9080Thanks @jfmcdowell! - Fixed formatting of Markdown block quotes inside deeply indented list items. WithproseWrap: "always", consecutive quote lines now wrap together within the same quote, while setext headings and fenced code blocks keep their structure.10. item> first line> second line> first line second line -
#12607
896d53eThanks @xucian! - Fixed #12542: the Markdown formatter is now idempotent when it formats tables.| a | b || -------- | ----- || x | `y` z || `p` z`q` | r || a | b || --------- | ----- || x | `y` z || `p` z `q` | r | -
#12692
8ff63f4Thanks @NikitaCOEUR! - Fixed thelinux-x64-muslbinary not using jemalloc, which it already ships: it fell back to musl’s allocator, andbiome checkon several threads could take minutes instead of seconds, for example in Alpine-based CI images. -
#12682
fa7cf4cThanks @dyc3! - Fixed #12679: whenmarkdown.parser.frontmatterandmarkdown.formatter.formatEmbedsare enabled, the Markdown formatter keeps the frontmatter of a fenced Markdown code block as written. Previously, it formatted the frontmatter as a thematic break and a paragraph, which removed the indentation of its YAML.```markdown---verified:by: human---# Policy``` -
#12649
343c8caThanks @JamBalaya56562! - Fixed #12643 and #12669: Biome now migrates the Prettier optionbracketSpacingtoformatter.bracketSpacing, both at the top level and insideoverrides. JSON and GraphQL files are now formatted with the same bracket spacing as JavaScript files. -
#12640
167bb00Thanks @latin-1! - FixeduseSortedPropertiesto withhold sorting fixes that would change the effective values of overlapping declarations, physical/logical border or corner properties, or declarations followed byall. UpdatednoShorthandPropertyOverridesto recognize logical border, corner shape,position-try,text-box, andtransition-behavioroverrides. -
#12723
b6cbec8Thanks @dyc3! - Improved the performance ofbiome lint,biome check, andbiome cion files where rules report diagnostics with code fixes, by up to 12% with the default rules. -
#12664
6021da0Thanks @MindTooth! - Fixed Biome processingpnpm-lock.yamlfiles. These generated lockfiles are now protected from processing. -
#12501
90a4d74Thanks @ematipico! - Fixed an issue where the CLI, when it ran with--use-serveralongside an editor connected to the same daemon, checked the unsaved text of the files open in the editor instead of the files on disk, and could make the editor’s text get lost. The CLI now checks the files on disk, and every editor and CLI run connected to the daemon keeps its own text of the files it opens. -
#12519
9ae56baThanks @dyc3! - The rulenoVueVIfWithVFornow also reportsv-else-ifandv-elseon the same element asv-for.<div v-if="loading">Loading...</div><TodoItem v-else v-for="todo in todos" :todo="todo" /> -
#12702
df0f7ccThanks @dyc3! - Fixed parsing of default values in Vuev-forbindings. Biome now parses the default value as JavaScript, so it is formatted and linted like other template expressions instead of being reported as a parse error.<div v-for="{ value = gt('v-for default') } in rows" /> -
#12656
25a00a2Thanks @dyc3! - Fixed non-JSON files inside the global settings directories of Zed, VS Code, and Cursor being parsed as JSON. -
#12501
90a4d74Thanks @ematipico! - Fixed an issue where the language server kept using the previous parser options for open files after the configuration changed. Open files are now parsed again with the new options, for examplejson.parser.allowComments. -
#12656
25a00a2Thanks @dyc3! - Improved the performance of Biome when it processes many files by up to 7%. -
#12661
066a077Thanks @dyc3! - Added the nursery rulenoVueDeprecatedListeners. It reports references to$listeners, which Vue 3 removed, in Vue templates and component objects. For example, Biome now reports<div v-on="$listeners" />andthis.$listenersinside a Vue component.
2.6.5
Patch Changes
-
#12755
bbc4887Thanks @dyc3! - Added the new nursery rulenoArrayForEach, which reportsforEach()calls that can be written asfor...ofloops. Values known not to be arrays, such as aMapor aSet, are ignored.array.forEach((element) => {bar(element);}); -
#12777
ba692e4Thanks @dyc3! - Added the new nursery rulenoAwaitInPromiseMethods, which reportsawaitinside the array passed toPromise.all(),Promise.allSettled(),Promise.any(), orPromise.race(). Theawaitpauses the code before the method is called, so the promises no longer run at the same time.Promise.all([await promise, anotherPromise]); -
#12765
af84fb4Thanks @dyc3! - Added the new nursery rulenoChainedComparison, which reports comparisons chained likea < b < cora === b === c. JavaScript comparesawithbfirst, and then compares the resultingtrueorfalsewithc, so3 > 2 > 1isfalse.if (a < b < c) {} -
#12547
0a2073dThanks @dyc3! - Added the nursery rulenoDynamicDelete, which disallows usingdeletewith a property name that is computed at runtime. Fixed property names written as string or number literals are allowed.delete container[name]; -
#12481
ed7adc2Thanks @dyc3! - Added the nursery rulenoLateEventControl, which reports calls topreventDefault(),stopPropagation(), andstopImmediatePropagation()that run after the browser has finished handling the event, where they have no effect.element.addEventListener("click", async (event) => {await save();event.preventDefault();}); -
#12795
179666dThanks @dyc3! - Added the nursery rulenoMapSpread, which disallows spreading objects or arrays in the values returned bymap()andflatMap()callbacks. Each spread copies a whole object or array for every item, which is slow for large arrays. Its unsafe fix replaces an object that starts with a spread withObject.assign().const users = getUsers();const rows = users.map((user) => ({ ...user, role: getRole(user) })); -
#12793
d9a99fdThanks @dyc3! - Added the nursery rulenoMismatchedMapKey, which reportsget()andset()calls that use a different key than thehas()check before them. Checking one key and then using another is usually a copy-paste mistake.if (map.has(key)) {map.get(otherKey); // reported} -
#12342
1db7c0dThanks @vibbix! - Added the nursery rulenoMissingScssInterpolation, which disallows Sass variables and function calls in custom property values without#{}interpolation. Sass copies these values into the CSS unchanged, so the browser receives$gapormath.div(8px, 2)instead of their results. Its unsafe fix wraps variables in#{}.:root {--gap: $gap;--half: math.div(8px, 2);} -
#12792
de86b37Thanks @dyc3! - Added the nursery rulenoMissingThrow, which reports errors that are created withnewbut never thrown. Its unsafe fix adds the missingthrowkeyword.function check(value) {if (!value) {new Error("Missing value");}} -
#12790
c23e4c3Thanks @dyc3! - Added the new nursery rulenoObjectLiteralComparison, which reports comparisons with an empty object{}or an empty array[]. These comparisons never check whether a value is empty, because objects and arrays are compared by reference.if (value === {}) {} -
#12450
793f07dThanks @dyc3! - Added the new nursery rulenoPlaywrightUnsafeReferences, which reports functions passed topage.evaluate()orpage.addInitScript()that use variables declared outside of them. Playwright runs these functions in the browser page, where those variables don’t exist.const x = 7;await page.evaluate(() => x * 2); // reported: `x` must be passed as an argument -
#12388
a0160a4Thanks @vibbix! - Added the nursery rulenoPseudoElementInFunctionalPseudoClass, which disallows pseudo-elements inside:is(),:where(),:not()and:has(). Browsers drop these selectors, so the styles never apply to the pseudo-element..card:is(::before, ::after) {content: "";} -
#12779
bc1befbThanks @dyc3! - Added the new nursery rulenoSinglePromiseInPromiseMethods, which reports an array with a single element passed toPromise.all(),Promise.any(), orPromise.race(). The rule offers a fix that awaits the value directly or usesPromise.resolve().const result = await Promise.all([promise]); -
#12241
d96de1dThanks @dyc3! - Added the nursery rulenoSvelteBindValueOnCheckableInputs, which reportsbind:valueon checkbox and radio inputs in Svelte files. Users change whether these inputs are checked, not theirvalue, sobind:valuedoes not track their choice.<input type="checkbox" bind:value={accepted} /> -
#12764
e166d08Thanks @dyc3! - Added the new nursery rulenoSyncMethods, which reports calls to functions whose names end withSync, such asfs.readFileSync(). These calls block the program until they finish. TheallowAtRootLeveloption allows them outside of functions, and theignoreoption allows specific function names.const contents = fs.readFileSync("data.txt"); -
#12515
c0a4174Thanks @dyc3! - Added the nursery rulenoTanstackQueryVoidQueryFn, which disallows TanStack Query functions that don’t return any data. TanStack Query doesn’t acceptundefinedas the data of a query, so the query fails with an error.import { useQuery } from "@tanstack/react-query";useQuery({queryKey: ["todos"],queryFn: async () => {await fetch("/api/todos");},});The rule belongs to the
tanstackQueryandtypesdomains. -
#12482
1e6e407Thanks @dyc3! - Added the nursery rulenoUnnecessaryStringTrim, which reportstrim()calls beforestartsWith()orendsWith()when only one side of the string matters. UsetrimStart()ortrimEnd()instead.value.trim().startsWith("-"); -
#12772
a108773Thanks @dyc3! - Added the nursery rulenoUselessAwait, which reportsawaiton values that are never promises, such as literals, arrays, and the results of comparisons.await [fetchUser(), fetchPosts()]; -
#12783
d0931b0Thanks @dyc3! - Added the new nursery rulenoUselessLengthCheck, which reports array length checks that don’t change the result: a check that the array is empty next toevery(), a check that it isn’t empty next tosome(), or a check that it isn’t empty around afor...ofloop over the same array.if (array.length > 0 && array.some(Boolean)) {} -
#12488
93e0e73Thanks @dyc3! - Added the new nursery rulenoUselessTypeAssertion, which reports type assertions that don’t change the type of an expression, such as a non-null assertion on a value that can’t benullorundefined.function double(value: number): number {return value! * 2;} -
#12632
0e197b4Thanks @dyc3! - Added the nursery rulenoVueChildContent, which disallows content inside elements that usev-htmlorv-text. These directives replace the content of their element, so Vue discards anything written there.<template><div v-html="html">Loading...</div></template> -
#12616
cb7b888Thanks @dyc3! - Added the new nursery rulenoVueDeprecatedConfigKeyCodes, which reports uses ofVue.config.keyCodes. Vue 3 removed this option, so custom key names defined with it no longer work.Vue.config.keyCodes = { f1: 112 }; -
#12568
59f3a42Thanks @dyc3! - Added the nursery rulenoVueDeprecatedDestroyedLifecycle, which reports thebeforeDestroyanddestroyedlifecycle hooks in Vue components. Vue 3 renamed them tobeforeUnmountandunmounted, and no longer calls hooks with the old names.<script>export default {destroyed() {},};</script> -
#12654
bcb1e0fThanks @dyc3! - Added the nursery rulenoVueDeprecatedEventsApi, which reports calls to the$on,$off, and$onceinstance methods in Vue components. Vue 3 removed these methods, so calling them throws an error.<script>export default {mounted() {this.$on("start", handler); // reported},};</script> -
#12590
b9872efThanks @dyc3! - Added the nursery rulenoVueDeprecatedFunctionalTemplate, which reports thefunctionalattribute on the<template>of a Vue component. Vue 3 no longer supports this attribute.<template functional><div>{{ props.message }}</div></template> -
#12552
b71b705Thanks @dyc3! - Added the nursery rulenoVueDeprecatedHtmlElementIs, which disallows theisattribute on HTML elements in Vue templates. Vue 3 no longer renders a component in place of these elements, unless the value starts withvue:.<template><tr is="my-row"></tr></template> -
#12553
4a613e1Thanks @dyc3! - Added the nursery rulenoVueDeprecatedInlineTemplate, which disallows theinline-templateattribute on Vue components. Vue 3 removed this feature, so the content between the component’s tags is no longer used as its template.<template><my-component inline-template><div>{{ message }}</div></my-component></template> -
#12617
0e9ca5bThanks @dyc3! - Added the nursery rulenoVueDeprecatedModelDefinition, which reports themodeloption in Vue components. Vue 3 ignores this option, sov-modelon the component always uses themodelValueprop and theupdate:modelValueevent.<script>export default {model: {prop: "checked",event: "change",},};</script> -
#12604
e998921Thanks @dyc3! - Added the nursery rulenoVueDeprecatedPropsDefaultThis, which reportsthisinside the function that computes the default value of a Vue prop. Vue doesn’t give this function access to the component, sothisdoesn’t point to it. Read other props from the function’s first argument instead.<script>export default {props: {size: Number,sizes: {type: Array,default() {return [this.size];},},},};</script> -
#12633
f65fe1eThanks @dyc3! - Added the nursery rulenoVueDeprecatedSlotAttribute, which reports theslotattribute in Vue templates. Vue 3 no longer uses this attribute to fill named slots, so usev-slot(or#) on a<template>element instead.<template><MyComponent><template slot="header">Title</template></MyComponent></template> -
#12589
8ccb19aThanks @dyc3! - Added the new nursery rulenoVueDeprecatedVBindSync, which reports the.syncmodifier on Vuev-binddirectives. Vue 3 removed this modifier, so the rule suggestsv-modelwith the same argument instead.<MyComponent :title.sync="pageTitle" /> -
#12609
e1e102bThanks @dyc3! - Added the new nursery rulenoVueDeprecatedVOnNativeModifier, which disallows the.nativemodifier on Vue’sv-ondirective. Vue 3 removed this modifier.<MyComponent @click.native="onClick" /> -
#12667
de354e7Thanks @dyc3! - Added the new nursery rulenoVueExcessiveProps, which reports Vue components that declare more props than themaxPropsoption allows. The default limit is10.<!-- With "maxProps": 2 --><script setup lang="ts">defineProps<{ title: string; subtitle: string; icon: string }>(); // reported</script> -
#12666
c3dc557Thanks @dyc3! - Added the nursery rulenoVueLoneTemplate, which reports<template>elements inside a Vue template that don’t usev-if,v-else-if,v-else,v-for, orv-slot. Vue renders these as regular HTML<template>elements, so their content isn’t shown.<template><template><p>Hello</p></template></template> -
#12533
4b1089dThanks @dyc3! - Added the new nursery rulenoVueMixin, which reports themixinsoption in Vue components. In Vue 3, composables are the recommended way to share logic between components. The rule is recommended and part of thevuedomain.<script>export default {mixins: [counterMixin],};</script> -
#12658
807e358Thanks @dyc3! - Added the new nursery rulenoVueMultipleObjectsInClass, which reports:classarrays in Vue templates that contain more than one object. Merge the conditional classes into a single object instead.<template><div :class="[{ active: isActive }, { disabled: isDisabled }]" /></template> -
#12564
78c1dd5Thanks @dyc3! - Added the nursery rulenoVueRefObjectReactivityLoss, which reports reads of a Vue ref’s value that run only once, in the same function that creates the ref. Such a read copies the current value, and the copy doesn’t update when the ref changes.import { ref } from "vue";const count = ref(0);const doubled = count.value * 2; -
#12517
5044c56Thanks @dyc3! - Added the nursery rulenoVueRestrictedCallAfterAwait, which reports calls to configured functions that come after anawaitin a Vue component’ssetup()function.For example, with
{ "functions": [{ "module": "vue-i18n", "path": "useI18n" }] }, the following call is reported:<script>import { useI18n } from "vue-i18n";export default {async setup() {await fetchUser();const { t } = useI18n();return { t };},};</script> -
#12558
e898da4Thanks @dyc3! - Added the nursery rulenoVueRestrictedVOn, which reportsv-onevent listeners that are disallowed through thelistenersoption. An entry can match an event name, a set of modifiers, and an element. For example, with{ "listeners": [{ "event": "click", "element": "MyButton" }] },<MyButton @click="onClick" />is now reported. -
#12573
65c6b0bThanks @dyc3! - Added the new nursery rulenoVueTemplateKey, which disallows thekeyattribute on<template>elements in Vue files. Akeyon a<template>that also usesv-foris still allowed.<template><template :key="item.id"><div /></template></template> -
#12629
2a34da1Thanks @dyc3! - Added the new nursery rulenoVueTemplateShadow, which disallowsv-forandv-slotvariables that hide a variable with the same name from an outer scope of a Vue template.<template><div v-for="item in groups"><span v-for="item in item.children">{{ item }}</span></div></template> -
#12610
40de561Thanks @dyc3! - Added the new nursery rulenoVueTextareaMustache, which disallows{{ }}text interpolation inside a Vue<textarea>. Vue doesn’t support it there; usev-modelinstead.<template><textarea>{{ message }}</textarea></template> -
#12665
7742209Thanks @dyc3! - Added the new nursery rulenoVueThisInBeforeRouteEnter, which reportsthisin thebeforeRouteEnternavigation guard of a Vue component. Vue Router calls this guard before it creates the component, sothisisundefinedthere.<script>export default {beforeRouteEnter(to, from, next) {this.loadUser(to.params.id); // reportednext();},};</script> -
#12620
70d7173Thanks @dyc3! - Added the nursery rulenoVueThisInTemplate, which reportsthisin Vue templates. Templates can read the properties of the component directly, sothis.textcan be written astext:<template><p>{{ this.text }}</p></template> -
#12601
1d4ed92Thanks @dyc3! - Added the new nursery rulenoVueUndeclaredEmits, which reports events that a Vue component emits without declaring them in theemitsoption or indefineEmits().<script setup>const emit = defineEmits(["change"]);emit("close"); // reported: "close" is not declared</script> -
#12583
4e870a8Thanks @dyc3! - Added the nursery rulenoVueUndeclaredProperties, which reports names that a Vue component uses but doesn’t declare, in its template, inthis.name, and inprops.name.<script setup>const count = 0;</script><template><!-- `cnt` isn't declared --><p>{{ cnt }}</p></template> -
#12657
b45fe79Thanks @dyc3! - Added the new nursery rulenoVueUndeclaredSlots, which reports<slot>elements in Vue components written in TypeScript when the slot isn’t declared withdefineSlots()or with theslotsoption.<script setup lang="ts">defineSlots<{default(props: { msg: string }): any;}>();</script><template><slot name="footer" /> <!-- reported --></template> -
#12789
041c800Thanks @dyc3! - Added the new nursery rulenoVueUselessTemplateAttributes, which reports attributes and directives that have no effect on a<template>element withv-if,v-else-if,v-else,v-for, orv-slotin Vue files. Vue renders only the content of such an element, so it ignores the other attributes.<template><template v-if="visible" class="heading">Title</template></template> -
#12592
36531ccThanks @dyc3! - Added the nursery rulenoVueUselessVBind, which reportsv-binddirectives whose value is a fixed string. A plain attribute does the same thing.<template><div :id="'foo'" /> <!-- reported, use id="foo" instead --></template> -
#12522
59838bbThanks @dyc3! - Added the nursery rulenoVueVForTemplateKeyOnChild, which reports akeyplaced on a child element of a<template v-for>instead of on the<template>tag.<template><template v-for="todo in todos"><TodoItem :key="todo.id" /></template></template> -
#12516
2d9e57eThanks @dyc3! - Added the nursery ruleuseAccessorPairs. The rule reports setters that have no matching getter in object literals, classes, and property descriptors.const user = {set name(value) {this._name = value;},}; -
#12756
1c6e3efThanks @dyc3! - Added the new nursery ruleuseObjectFromEntries, which reports code that builds an object from a list of key-value pairs withreduce(), afor...ofloop, or_.fromPairs()instead ofObject.fromEntries(). Thefunctionsoption adds other helper functions to report.const object = pairs.reduce((object, [key, value]) => ({ ...object, [key]: value }), {}); -
#12778
5432756Thanks @dyc3! - Added the new nursery ruleuseSetSize, which reports code that copies aSetinto an array only to read the array’slength, and suggests reading thesizeproperty of theSetinstead.const uniqueCount = [...new Set(userIds)].length; -
#12302
b0d3390Thanks @dyc3! - Added the nursery ruleuseSvelteStoreInitialValue, which requireswritable(),readable(), andderived()stores fromsvelte/storeto be created with an initial value.import { writable } from "svelte/store";export const count = writable(); -
#12290
c973fedThanks @dyc3! - Added the nursery ruleuseTailwindVariablesShorthandfor JavaScript and HTML. It reports Tailwind CSS classes that read a CSS variable with[var()], and fixes them to the shorthand that Tailwind CSS v4 added.<div className="bg-[var(--brand)]" />; // use `bg-(--brand)` -
#12518
e9d9616Thanks @dyc3! - Added the nursery ruleuseTanstackQueryStableQueryClient, which reports a TanStack QueryQueryClientcreated inside a React component or custom hook. Such a client is created again on every render, and its cache starts empty each time.import { QueryClient, QueryClientProvider } from "@tanstack/react-query";function App() {const queryClient = new QueryClient();return <QueryClientProvider client={queryClient}><Home /></QueryClientProvider>;} -
#12650
0ddd08fThanks @dyc3! - Added the nursery ruleuseVueBlockOrder, which enforces the order of the top-level blocks in Vue components. By default,<script>and<template>blocks come first, in any order, followed by<style>blocks. The order can be changed with theorderoption.<style></style><script></script> -
#12715
7863f32Thanks @dyc3! - Added the nursery ruleuseVueBooleanPropTypeFirst, which requiresBooleanto come first in the list of types of a Vue prop. WhenStringcomes beforeBoolean, a prop written in a template without a value is set to an empty string instead oftrue.<script setup>defineProps({disabled: [String, Boolean],});</script> -
#12563
91ac4cbThanks @dyc3! - Added the nursery ruleuseVueComputedPropertyReturn, which requires the getters of Vue computed properties to return a value on every path.<script setup>import { computed, ref } from "vue";const count = ref(0);const double = computed(() => {count.value * 2; // reported: the getter never returns a value});</script> -
#12716
ae535eaThanks @dyc3! - Added the new nursery ruleuseVueConsistentBooleanPropStyle, which enforces a consistent style for Vue component props set totrue. By default, it requires the shorthand form; thestyleoption can require the longhand form instead.<template><MyComponent :disabled="true" /></template> -
#12675
2a16d59Thanks @dyc3! - Added the new nursery ruleuseVueConsistentDefineEmitsDeclaration, which enforces one declaration style fordefineEmitsin<script setup lang="ts">. By default, events must be declared with a type. Thestyleoption can instead require each event to be a property of that type, such aschange: [id: number], or require an argument, such asdefineEmits(["change"]).<script setup lang="ts">const emit = defineEmits(["change", "update"]);</script> -
#12612
ab53e4fThanks @dyc3! - Added the nursery ruleuseVueConsistentPropNameCasing, which requires prop names in Vue components to use one casing style. By default, prop names must be in camelCase. Thecasingoption switches the rule to snake_case.<script setup>defineProps({greeting_text: String,});</script> -
#12608
0928a75Thanks @dyc3! - Added the nursery ruleuseVueConsistentVForDelimiter, which requires the same word,inorof, between the item and the list in every Vuev-fordirective. The default isin, and thedelimiteroption switches it toof.<!-- reported by default --><div v-for="item of items"></div> -
#12611
d2df495Thanks @dyc3! - Added the nursery ruleuseVueConsistentVSlotStyle, which enforces one style for Vue slots:#name,v-slot:name, orv-slotfor the default slot. By default, it expectsv-sloton a component and#on<template>elements.<template><MyComponent><template v-slot:header>Title</template></MyComponent></template> -
#12780
69467e0Thanks @dyc3! - Added the nursery ruleuseVueDefaultExport, which reports a<script>block of a Vue component that has no default export, when the file has no<script setup>block.<script>const foo = "foo";</script> -
#12655
8a576b4Thanks @dyc3! - Added the nursery ruleuseVueDefaultProp, which reports optional props of Vue components that have no default value. Props that only acceptBooleanare not reported.For example, the following component doesn’t say what
sizeis when a parent component leaves it out:<script setup>defineProps({size: Number,});</script> -
#12676
530000aThanks @dyc3! - Added the nursery ruleuseVueEmitValidator, which requires a validator function for each event declared in theemitsoption or indefineEmits().<script setup>// Reported: the event "change" has no validator function.defineEmits(["change"]);</script> -
#12605
093c7caThanks @dyc3! - Added the new nursery ruleuseVueEmitsValidatorReturn, which reports Vue event validators that never return a true value. Vue prints a warning in development mode each time such an event is emitted.<script setup>defineEmits({submit(payload) {payload.email.includes("@");},});</script> -
#12668
1690307Thanks @dyc3! - Added the new nursery ruleuseVueMacroVariableName, which requires specific variable names for the results ofdefineProps(),defineEmits(),defineSlots(),useSlots()anduseAttrs()in Vue<script setup>blocks. The names can be changed with the rule’s options.<script setup>const propsDefined = defineProps({ msg: String }); // reported, should be `props`</script> -
#12773
8f28e3fThanks @dyc3! - Added the nursery ruleuseVueOneComponentPerFile, which reports files that define more than one Vue component. The rule counts<script setup>blocks,export default { ... }in.vuefiles, anddefineComponent()andcreateApp()calls that define a component in place with an options object or a setup function. It doesn’t report the main component of a.vuefile.<script setup>import { defineComponent, h } from "vue";const Badge = defineComponent({render: () => h("span", "New"),});</script> -
#12571
a357b2fThanks @dyc3! - Added the new nursery ruleuseVuePropTypeConstructor, which reports Vue prop types that aren’t constructors, such as a type name written as a string.<script>export default {props: {size: 'Number', // reported, use `Number` instead},};</script> -
#12566
e69572bThanks @dyc3! - Added the nursery ruleuseVueRenderReturn, which requires therenderfunction of a Vue component to return a value on every path.The following example is invalid because the
renderfunction returns nothing whenthis.visibleisfalse:<script>import { h } from "vue";export default {render() {if (this.visible) {return h("div", "hello");}},};</script> -
#12619
3703a36Thanks @dyc3! - Added the nursery ruleuseVueSeparateStaticClass, which reports class names in a Vue:classbinding that always apply, such asheaderin<div :class="['header', theme]">. These classes belong in the plainclassattribute. -
#12677
f6b7f15Thanks @dyc3! - Added the nursery ruleuseVueSingleEventPayload, which reports Vue component events that are emitted or declared with more than one value. A listener written inline in a template, such as@change="onChange($event)", only receives the first value.<script setup>const emit = defineEmits(["change"]);emit("change", value, extra);</script> -
#12646
3d92356Thanks @dyc3! - Added the new nursery ruleuseVueSlotNameCasing, which enforces a consistent casing for the names of<slot>elements in Vue templates. Slot names must be in camelCase by default. Thecasingoption can require kebab-case or a single lowercase word instead.<template><slot name="foo-bar" /></template> -
#12572
cb16268Thanks @dyc3! - Added the nursery ruleuseVueSlotsAsFunctions, which reports slots inthis.$slotsthat are used as their content instead of being called. In Vue 3, each slot is a function that returns its content.export default {render() {return this.$slots.default.filter(isVisible); // reported},}; -
#12659
e7691f7Thanks @Object,! - Added the new nursery ruleuseVueTypedObjectProps, which reports Vue props declared withObjectorArraywithout a TypeScript type in TypeScript files and Vue files with<script lang="ts">.<script setup lang="ts">defineProps({// reporteditems: Array as PropType<string[]>,});</script> -
#12574
bb8ca38Thanks @dyc3! - Added the nursery ruleuseVueValidAttributeName, which reports invalid attribute names in Vue templates, including names bound withv-bind. Attributes on components aren’t checked.<template><p 0abc :-def="value"></p></template> -
#12582
f6ac8ebThanks @dyc3! - Added the nursery ruleuseVueValidDefaultProp, which requires the default value of a Vue prop to match the type of the prop. Default objects and arrays must also be returned from a function, so that each component instance gets its own copy.<script>export default {props: {count: { type: Number, default: "zero" }, // reporteditems: { type: Array, default: [] }, // reported},};</script> -
#12613
071324dThanks @dyc3! - Added the nursery ruleuseVueValidDefineOptions, which reports invalid calls to Vue’sdefineOptions()macro in<script setup>. It reports a call that is repeated, that has no options or has type arguments, that declaresprops,emits,expose, orslots, or that uses variables declared in<script setup>.<script setup>const options = { name: "Foo" };defineOptions(options);</script> -
#12557
f1eb303Thanks @dyc3! - Added the new nursery ruleuseVueValidNextTick, which reports VuenextTickcalls that don’t wait for Vue to update the page. The rule is recommended and part of the Vue domain.import { nextTick } from "vue";nextTick(); // reported: the Promise is ignorednextTick.then(callback); // reported: `nextTick` isn't called -
#12674
361c9f2Thanks @dyc3! - Fixed #12672: Astro and Svelte formatting now preserves comments and whitespace inside preformatted elements such as<pre>and<textarea>.<pre><code>Hello</code></pre><pre><!-- hello --><code>Hello</code></pre> -
#12746
2ebd7b6Thanks @ematipico! - Improved #2730: Biome now reports the active analyzer rule and source range when a rule panics, and suggests disabling the rule as a workaround. -
#12758
1df6d85Thanks @dyc3! - Fixed #12739, #12741, and #12742: the Markdown formatter now adds a blank line between a top-level paragraph and a header, fenced code block, list, or blockquote that directly follows it, matching Prettier.Some text:- bullet 1- bullet 2 -
#12806
03261deThanks @Jayllyz! - Added the nursery ruleuseTanstackQueryInfiniteQueryPropertyOrder, which enforces the orderqueryFn,getPreviousPageParam,getNextPageParamin the options of TanStack Query infinite queries. TanStack Query infers types from this order.import { useInfiniteQuery } from "@tanstack/react-query";useInfiniteQuery({getNextPageParam: (lastPage) => lastPage.nextId,queryFn: ({ pageParam }) => fetchProjects(pageParam),}); -
#12762
69187a9Thanks @dyc3! - Fixed #12738: the Markdown formatter now collapses consecutive blank lines between blocks into a single blank line.Some paragraph.## Next section -
#12708
e87ec37Thanks @nhedger! - Fixed.editorconfigsection globs that skipped the character following a bracket expression. For example,[{[ab],c}.json]now matchesa.json,b.json, andc.json. -
#11623
37440f9Thanks @Bsibz! - Fixed #11548: ThetypeMemberselector ofuseNamingConventionno longer applies to TypeScript type parameters. -
#12106
ff1d8b8Thanks @dyc3! - Added the nursery rulenoExcessiveNestedBlocks, which reports blocks nested deeper than the configured maximum (4 by default). It checksif,switch,try, and loop statements in JavaScript, and nested rules and at-rules in CSS. -
#12747
397b0ebThanks @ematipico! - Fixed #8094: Biome’s language server now skips unchanged dynamic capability registrations, preventing duplicate watched-file notifications in affected editors. -
#12708
e87ec37Thanks @nhedger! - Fixed #12683:.editorconfigsection globs with nested braces, such as[{*.{js,json},biome.jsonc}], are now supported instead of being ignored. -
#12910
6f8313dThanks @dyc3! - Fixed a slowdown inbiome lint,biome checkandbiome formatthat grew with the number of files: looking up an open file took longer after every file Biome had already processed. Large projects are processed faster again. -
#12787
53c3a49Thanks @dyc3! - Fixed the GritQL formatter treating a single line break between list items as a blank line. Formatting a broken list no longer adds blank lines between its items, and blank lines from the source are still kept.$x <: [`1`,`2`,`1`, `2`,`3`] -
#12864
c2c2590Thanks @nhedger! - Fixed #12862: Biome now applies the options under the top-levelgritconfiguration key. Previously, options such asgrit.formatter.lineWidthandgrit.formatter.enabledwere ignored, and Grit files were formatted with the globalformattersettings. -
#12543
0ec0a72Thanks @dyc3! - FixednoVueUndeclaredDirectivesnot reporting undeclared custom directives in components that export their options withexport { options as default }.<script>const options = {};export { options as default };</script><template><div v-highlight></div></template> -
#12745
86be8b8Thanks @vidigoat! - Fixed the formatter removing the parentheses that end an optional chain when a non-null assertion, type arguments or more parentheses follow them. The output either short-circuited the rest of the chain, as ina?.b!.cfor(a?.b)!.c, or didn’t parse, as withnew a?.b!(), a template tag or an assignment target.a?.b!.c;(a?.b)!.c;new a?.b!();new (a?.b)!();a?.b`template`;(a?.b)`template`; -
#12821
44626baThanks @Suto-Michimasa! - Fixed #12820:usePlaywrightValidDescribeCallbackno longer reports an anonymoustest.describe(callback)as a missing callback.test.describe(() => {test.use({ colorScheme: "dark" });}); -
#12819
b620cbcThanks @Suto-Michimasa! - Fixed #12766:usePlaywrightValidDescribeCallbackno longer reportstest.describe(title, details, callback). The rule now validates the last argument as the callback, as the original ESLint rule does.test.describe("suite", { tag: "@smoke" }, () => {}); -
#12898
291f034Thanks @dyc3! - Fixed #12882: the Tailwind class parser no longer reports a parse error for unknown utilities with a dashed name and an arbitrary value or a CSS variable, such asfoo-bar-[1px]orfoo-bar-(--my-var).useTailwindSortedClassessorts these classes first, like other unknown classes. -
#12639
bd19436Thanks @dyc3! - Fixed #12623: the safe fix ofuseConsistentTestItno longer leaves an unused import when applied to every call in a file. When all calls to an imported test function are renamed, the import is now replaced with an alias, such astest as it, instead of keeping the original specifier. When the original specifier is kept, the alias is now added astest, test as itinstead oftest , test as it. -
#12870
378798fThanks @dyc3! - Improved the performance of grit plugins that use regexes. -
#12769
6d23980Thanks @ematipico! - Fixed #12757: the Markdown formatter no longer turns an indented paragraph line that starts with-,1.,#, or>into a list, heading, or blockquote. Such a line now joins the previous line, matching Prettier.-- Item- Nested item+- Item - Nested itemcontinuation line -
#12737
162ed76Thanks @xgbtxy! - Fixed #12726:useMathMinMaxnow recognizes directly listed nonnumeric elements in array reductions, such as["foo", "bar"].reduce((a, b) => a > b ? a : b). This also covers Date values and local constant arrays used only by reductions, including parentheses and TypeScript assertions. Spread elements and other unclassified inputs retain their existing behavior. -
#12782
44d6768Thanks @dyc3! - Added the new nursery rulenoInvalidRemoveEventListener, which reports calls toremoveEventListener()that pass an inline function or the result of.bind(). These create a new function, so the listener that was added is never removed.window.removeEventListener("click", listener.bind(window)); -
#12858
b312e95Thanks @dyc3! - Fixed #12851: a plugin that throws or fails to run now reports an error diagnostic instead of an info diagnostic, sobiome lintandbiome checkexit with a non-zero code. -
#12813
a55d360Thanks @dyc3! - Improved the performance of JavaScript plugins that readnode.kindortoken.kind. -
#12913
4ada6fcThanks @dyc3! - Fixed #12909: Biome no longer crashes with an access violation when formatting, linting or checking files on Windows ARM64. -
#12443
cccbc03Thanks @dyc3! - Fixed the code fixes ofnoMisusedPromises,noFloatingPromises, andnoVueDataObjectDeclarationduplicating comments attached to the wrapped expression. For example, thenoFloatingPromisesfix for an array of promises preceded by a comment no longer copies that comment intoPromise.all(...). -
#12769
6d23980Thanks @ematipico! - Fixed #12768: the Markdown formatter no longer splits a blockquote in two when an empty>line separates its list items.> - one> - two>> - three -
#12769
6d23980Thanks @ematipico! - Fixed #12767: the Markdown formatter no longer moves a list item out of a blockquote when the item follows a nested list item. The formatter also keeps the>of a line that directly follows a list inside a blockquote and starts a nested blockquote, a heading, or a different list.> - one> - nested- two> - two -
#12769
6d23980Thanks @ematipico! - Fixed #12703: the Markdown formatter no longer indents the empty>line between a list and a paragraph in a blockquote. Formatting again no longer moves the paragraph out of the quote.> - item one> continued.>>> Paragraph line one> line two. -
#12465
5127af1Thanks @Th3S4mur41! - ExpandeduseLogicalPropertiesto report multi-value physical shorthands and logical longhand pairs that can be combined. Dynamic shorthands such aspadding: var(--spacing) 2pxare also reported without an automatic fix because the variable may supply multiple values.
-
#12860
31f1820Thanks @vibbix! - Fixed the SCSS formatter joining comma-separated multi-value declarations onto one line. SCSS now prints them one value per line, as the CSS formatter and Prettier do..a {transition: opacity 1s, color 2s;transition:opacity 1s,color 2s;} -
#12868
ac70a85Thanks @dyc3! - Addednode.descendants(kinds)andnode.walk(kinds, enter, exit)to JavaScript plugins. They find the nodes inside a node whose kind is in a set created withnodeKinds(), and are much faster than visiting every node withnode.children().const CALLS = nodeKinds("JS_CALL_EXPRESSION");for (const call of root.descendants(CALLS)) {registerDiagnostic(call, "information", "Found a call.");} -
#12786
126c172Thanks @dyc3! - Added theallowBlackAndWhiteoption tonoTailwindRawColors. It defaults totrue. When set tofalse, the rule also reports classes that useblackorwhite, such asbg-whiteandtext-black/50, and suggests similar colors from your theme whentailwind.stylesheetis set.{ "options": { "allowBlackAndWhite": false } } -
#12754
a00eb5aThanks @dyc3! - Fixed #12724: whenproseWrapis"always"or"never", the Markdown formatter now wraps the text inside emphasis, strong emphasis, and strikethrough like the surrounding prose, instead of keeping their source line breaks and forcing line breaks around them. Text inside block quotes keeps its current formatting. With alineWidthof 50:Some words before the strong text,**stop and tellthem**after the strong text.Some words before the strong text, **stop and tellthem** after the strong text. -
#12708
e87ec37Thanks @nhedger! - Fixed.editorconfigsection globs with unbalanced braces. As in the EditorConfig reference implementation, all braces in such a glob are now matched literally, so[{a,b}}.json]only matches a file named{a,b}}.json.
2.6.6
Patch Changes
-
#12887
da0422eThanks @dyc3! - Added the new nursery rulenoArrayMethodsOnArguments. It reports calls to array methods on theargumentsobject, which isn’t an array, so these calls throw aTypeErrorwhen the code runs.function sum() {return arguments.reduce((total, value) => total + value, 0);} -
#12877
cd9e10fThanks @dyc3! - Added the nursery rulenoConstantComparisons, which reports&&and||conditions that can never be true, are always true, or contain a check with no effect.if (statusCode <= 400 && statusCode > 500) {} -
#12876
a7c9586Thanks @dyc3! - Added the nursery rulenoErasingOperation, which disallows operations with0that always result in zero: multiplying by0, a bitwise AND with0, and dividing0by a number. The other value in these operations has no effect on the result, which usually means the code has a mistake.const total = price * 0; -
#12841
e954f55Thanks @dyc3! - Added the nursery rulenoNegatedArrayPredicate, which reports negated calls toArray#some()andArray#every()and suggests moving the negation into the callback function.// Invalid: use `array.every((item) => !isUnicorn(item))` instead.const isMissing = !array.some((item) => isUnicorn(item)); -
#12888
15039f7Thanks @dyc3! - Added the new nursery rulenoNumberArgumentOutOfRange, which reports number literal arguments oftoString(),toFixed(),toExponential()andtoPrecision()that are outside the range the method accepts. These calls throw aRangeErrorat runtime.value.toString(64); -
#12889
1cd7520Thanks @dyc3! - Added the nursery rulenoSharedBranchCode, which reports code that is repeated at the start or end of every branch of anifstatement. That code runs no matter which branch is taken, so it can be moved before or after theifstatement.if (condition) {doSomething();cleanup();} else {doSomethingElse();cleanup();} -
#12842
d47fcfdThanks @dyc3! - Added the new nursery rulenoSubtractionComparison, which reports subtracting two values only to compare the difference with0, and suggests comparing the values directly.if (a - b > 0) {} -
#12866
7c1cd5fThanks @dyc3! - Added the nursery rulenoSvelteIgnoredUnsubscribe, which reports calls to a store’ssubscribe()method when the returned function is ignored. Without that function, the subscription can never be stopped, which causes a memory leak.<script>import { count } from "./stores.js";count.subscribe((value) => console.log(value));</script> -
#12890
6b73fcfThanks @dyc3! - Added the new nursery rulenoUninvokedArrayCallback, which reports array methods such asmap()andforEach()called with a callback on an array that only has empty slots. The callback never runs in this case.const list = new Array(5).map(() => createElement()); -
#12886
3bb18d8Thanks @dyc3! - Added the nursery ruleuseNextScriptForGoogleAnalytics, which reports<script>elements that load Google Analytics or Google Tag Manager. Use theGoogleAnalyticsandGoogleTagManagercomponents from@next/third-parties/googleinstead, which load these scripts after the page becomes interactive.<script async src="https://www.googletagmanager.com/gtag/js?id=G-XYZ" />The rule belongs to the
nextdomain. -
#12309
0538e30Thanks @dyc3! - Added the new nursery ruleusePackageJsonCpu, which reportspackage.jsonfiles that have nocpufield. Thecpufield lists the processor types that the package supports.The following
package.jsonfile satisfies the rule:{"name": "my-package","version": "1.0.0","cpu": ["x64", "arm64"]} -
#12310
191111dThanks @dyc3! - Added the nursery ruleusePackageJsonEngines, which reportspackage.jsonfiles that have noenginesfield.A
package.jsonpasses the rule once it declares the field:{"name": "my-package","engines": {"node": ">=20"}} -
#12986
cc929afThanks @dyc3! - Fixed #12954, where configuring rules in groups with more than 256 rules could enable or disable the wrong rule. -
#12931
fe9248eThanks @dyc3! - Improved the performance of linting. Each lint pass now spends less time stepping over syntax nodes that no enabled rule looks at. -
#12969
22d27e8Thanks @vibbix! - Improved the performance of CSS linting. Rules that compare selectors, such asnoDescendingSpecificityandnoDuplicateSelectors, now make fewer memory allocations. -
#12973
5a06df5Thanks @vibbix! - FixeduseGenericFontNamesreportingfont-familyinside@font-palette-values. There,font-familynames the font families the palette applies to, so it doesn’t take a generic family.@font-palette-values --palette {font-family: Bixa;override-colors: 0 red;} -
#12930
ce71284Thanks @dyc3! - Fixed #12073:useExhaustiveSwitchCasesnow reports non-exhaustive switches over values read fromfor...ofloops overArray.prototype.entries(),Map, andSet, and over properties of array elements indexed by anumbervariable.noMisusedPromisesnow also reports Promise-returning callbacks passed to array methods such asfindandevery. -
#12983
2987b54Thanks @ashokram-si! - Fixed #12957: Biome now correctly parses SCSS negative interpolation list items as separate values instead of an invalid subtraction operator.margin: -#{$s} - #{$s} - #{$s} auto;margin: -#{$s} -#{$s} -#{$s} auto;
2.6.7 Latest
Patch Changes
-
#12906
b3375d2Thanks @dyc3! - Added the nursery rulenoAsyncPromiseFinally, which reports async functions passed to a promise’s.finally()method. If such a function fails, its error replaces the original result or error of the promise.promise.finally(async () => {await cleanup();}); -
#12894
e24da6fThanks @dyc3! - Added the nursery rulenoDuplicateTypeConstituents, which reports types listed more than once in a union or intersection type, andundefinedin the type of an optional parameter.type T = string | number | string;function f(a?: string | undefined) {} -
#12899
6c15027Thanks @dyc3! - Added the nursery rulenoExcessiveSelectorComplexity, which limits how many IDs, type selectors, attribute selectors, pseudo-classes, universal selectors, compound selectors, and combinators a CSS selector can contain. It can also disallow chosen combinators, pseudo-classes, pseudo-elements, attributes, and attribute operators. The rule does nothing until an option is set.For example, with
"maxIds": 1, the following selector is reported:#main #sidebar {} -
#12897
0b8f429Thanks @dyc3! - Added the new nursery rulenoInvalidFetchOptions, which reports abodyin the options offetch()andnew Request()when the method isGETorHEAD. These calls throw aTypeErrorat runtime. When nomethodis given, the request usesGET.await fetch("/", { method: "GET", body: "foo=bar" }); -
#12926
9b6b9f4Thanks @dyc3! - Added the nursery rulenoNewArray, which reportsnew Array()calls with a single argument. Such a call creates an empty array of the given length when the argument is a number, and an array that holds the argument otherwise.const array = new Array(length); -
#12895
739440fThanks @dyc3! - Added the new nursery rulenoRedundantTypeConstituents, which reports members of union and intersection types that have no effect, such as a literal type next to its primitive type, orneverin a union.type Status = "active" | string; -
#12810
71ab61bThanks @dyc3! - Added the nursery rulenoSvelteAsyncStore, which disallows passing async functions to thewritable(),readable(), andderived()stores fromsvelte/store.import { writable } from "svelte/store";const user = writable(null, async (set) => {set(await fetchUser());}); -
#12917
37d9f41Thanks @dyc3! - Added the new nursery rulenoUnresolvedDefaultImport, which reports default imports from modules that have no default export. The rule is part of theprojectdomain.// foo.js only contains `export function foo() {}`import foo from "./foo.js"; -
#12892
f16842eThanks @dyc3! - Added the nursery rulenoUselessFallbackInSpread, which reports empty object fallbacks when spreading a value into an object. Spreadingnull,undefined, or another falsy value into an object adds no properties, so the fallback has no effect.const object = { ...(options || {}) }; -
#12785
c198be2Thanks @dyc3! - Added the new nursery rulenoUselessParameterPropertyAssignment, which reports constructor assignments such asthis.name = namewhennameis a parameter property. TypeScript already sets the property to the parameter’s value, so the assignment does nothing.class User {constructor(public name: string) {this.name = name;}} -
#12900
a4d1b0fThanks @dyc3! - Added the nursery rulenoUselessSpread, which reports spread syntax that has no effect. For example,[first, ...[second]]can be written as[first, second], andnew Set([...items])can be written asnew Set(items). -
#12902
d7d755bThanks @dyc3! - Added the nursery rulenoVueExposeAfterAwait, which reportsexpose()anddefineExpose()calls that come after anawaitin a Vue component’s setup code. These calls run too late, so a parent component might not receive the exposed properties.<script setup>await fetchUser();defineExpose({ reload });</script> -
#12596
d33e56eThanks @dyc3! - Added the nursery ruleuseAtomicUpdates, which reports assignments in async functions and generators that can be based on an outdated value because the function paused at anawaitoryieldafter reading it.let total = 0;async function addToTotal(getAmount) {total += await getAmount(); // reported} -
#12901
48e3572Thanks @dyc3! - Added the new nursery ruleuseConsistentBooleanName. It requires variables, parameters, and functions that hold or return a boolean to start with a prefix such asisorhas, and reports names with those prefixes that don’t hold or return a boolean.const completed = progress === 100;const hasName = "Sindre"; -
#12905
5b00387Thanks @dyc3! - Added the nursery ruleuseConsistentFontWeightNotation, which enforces writing font weights either as numbers or as the keywordsnormalandboldwhere possible. It checks thefont-weightandfontproperties, and its safe fix converts betweennormal/boldand400/700.a { font-weight: bold; } -
#12922
8d33c85Thanks @dyc3! - Added the nursery ruleuseConsistentTupleLabels, which reports tuple type elements without a label when other elements of the same tuple have one.type Point = [x: number, number]; -
#12925
7252cbdThanks @dyc3! - Added the new nursery ruleuseGlobalRegexInMatchAll, which reports calls tomatchAll()with a regular expression that doesn’t have thegflag. These calls throw aTypeErrorat runtime.text.matchAll(/pattern/); -
#12891
e781bc3Thanks @dyc3! - Added the nursery ruleuseGlobalRegexInReplaceAll, which reports regular expressions without thegflag passed toreplaceAll(). These calls throw aTypeErrorinstead of replacing text.withSpaces.replaceAll(/\s+/, ","); -
#12896
a968e1aThanks @dyc3! - Added the new nursery ruleuseValidCharacterComparison, which reports comparisons between a single character and a string that has more than one character. Such comparisons are alwaysfalse, or alwaystruewith!==and!=.text.charAt(0) === "ab"; -
#13085
7a795d0Thanks @ematipico! - Fixed withastro/compiler-rs#221 so Astro template expressions containing comment-only JSX expression children, such as<span>{<!-- x -->}</span>, parse without diagnostics. -
#12621
79ce388Thanks @latin-1! - Fixed #12413 and #12414:useSortedPropertiesnow sorts consecutive groups of properties independently, preserving the positions of nested rules, at-rules, and SCSS variable declarations. -
#13065
bd9faaeThanks @ematipico! - Fixed #5848: runninguseSortedKeysoruseSortedSelectionSetas an editor source action no longer corrupts nested objects or selection sets. -
#13056
98f4d53Thanks @ematipico! - Fixed #10607:noUndeclaredDependenciesno longer reports imports resolved through TypeScript’scompilerOptions.pathsmappings. -
#13033
7638393Thanks @GBra-4-669! - Fixed #12980: the CSS parser no longer panics on acomposesdeclaration whose value contains a non-identifier token, such ascomposes: 1px;. It reports a diagnostic instead. -
#12917
37d9f41Thanks @dyc3! - FixednoUnresolvedImports: it now reports default imports from modules that only forward exports withexport * from "...".export *never re-exports a default export, soimport foo from "./barrel.js"fails when./barrel.jscontains onlyexport * from "./foo.js". -
#12596
d33e56eThanks @dyc3! - FixednoUnreachableSuperignoring the default values of constructor parameters. Usingthisin a default value is now reported, because it runs beforesuper(), and callingsuper()in a default value is now recognized.class Child extends Parent {constructor(options = this.defaults()) { // reportedsuper(options);}} -
#12596
d33e56eThanks @dyc3! - FixednoUselessAssignmentignoring variables that are used in the iterated value of afor...oforfor...inloop, in the default values of a destructuring declaration or of parameters, or in the body of an arrow function written as a single expression. These variables are now checked too.function process(first, second) {let list = first; // reported: this value is never readlist = second;for (const item of list) {handle(item);}} -
#12805
2468384Thanks @vibbix! - Fixed #12332:noUnknownUnitno longer reports hex colors that start with a digit in SCSS custom properties or in unquoted legacy IEfiltervalues. The rule now accepts--accent: #4566a8;instead of reporting the unknown unita8. -
#12549
7fdb28fThanks @pkallos! - Fixed #10464:useNullishCoalescingno longer reports a ternary orifstatement that checks onlynullor onlyundefinedwhen the type can also be the other, because??would change its behavior. -
#12952
d1896a0Thanks @arendjr! - Addedgrit()queries to JavaScript plugins. A rule can now use a GritQL pattern to select the nodes passed torun()instead of listing syntax kinds withast().For example:
export const noConsole = defineRule({query: grit("`console.log($args)`"),run(element) {if (element.kind !== "JS_CALL_EXPRESSION") return;registerDiagnostic(element, "warning", "Unexpected console.log.");},});Usage of Grit patterns can be particularly useful when it would take several checks to verify the shape of a snippet that involves multiple AST nodes.
Grit sequence patterns call
run()for each matched node. Matching on leaf tokens is also supported for patterns, while patterns containing rewrites are rejected. Plugins using GritQL patterns should report diagnostics fromrun()as usual.Plugins using Grit queries can still request the semantic model as well:
export const rule = defineRule({query: grit("function $fn($args) { $body }", { semantic: true }),run(node, { model }) {// You can use `model` here similar to a query specified using `ast(..., { semantic: true })`.},}); -
#13022
81d0187Thanks @arendjr! - Fixed an issue where GritQL patterns wouldn’t match snippets if they contain a trailing list separator.For example, the pattern
`a, b`wouldn’t match the arguments infunction(a, b,), whereas now they do. -
#12999
ace98cfThanks @deepsingh132! - Fixed #12953: the Markdown formatter no longer removes the blank line between a blockquote that ends a list item and the block that follows it, matching Prettier. Removing that line could also move a following paragraph into the blockquote. The same applies to a list item that ends with a hard line break.- a> b#### Heading -
#13067
45c8c4dThanks @ematipico! - Added the nursery rulenoDisabledAttribute, which warns when buttons and other form controls use the nativedisabledattribute. A disabled control can’t be reached with the Tab key, so the rule suggestsaria-disabledorreadonlyinstead.<button disabled>Save</button><input type="email" disabled /> -
#12923
0668c8fThanks @dyc3! - Added the new nursery rulenoScssNullComparison. It reports comparisons tonullin Sass@ifand@else ifconditions, becausenullalready counts as false in a condition.a {@if $value == null {}} -
#12955
e1ef913Thanks @ematipico! - Fixed an issue where Biome could silently skip configured plugins. Biome now reports an error when those plugins are unavailable during analysis. -
#12997
419aa5dThanks @Riccardo-bit-cpu! - Fixed #12475:noSwitchDeclarationsno longer reportsvardeclarations insideswitchclauses, matching ESLint’sno-case-declarations. -
#12867
6a25d72Thanks @dyc3! - Added the nursery rulenoUselessQualifier, which reports namespace and enum names that are repeated before a member inside that same namespace or enum. Biome provides a fix that removes the repeated name.namespace Shapes {export type Point = { x: number; y: number };const origin: Shapes.Point = { x: 0, y: 0 };} -
#12050
60f4695Thanks @dor-sr! - Fixed #11933:useUnicodeRegexno longer offers to add theuflag to patterns that become invalid or change meaning in Unicode mode, such as/{/,/\-/or/[\d-z]/. The rule still reports them. -
#13035
478e056Thanks @dyc3! - Fixed #13026: the Markdown formatter no longer indents the rows of a table inside a blockquote when the table follows a paragraph of two or more lines. Previously, every run of the formatter indented the rows further until they were joined onto the header line.> First line of a paragraph,> second line of it.>> | A | B |> | --- | --- |> | x | y |> | --- | --- |> | x | y | -
#13066
f6cf28eThanks @arendjr! - Removed thesemantic()query function from the JavaScript plugin API. Pass{ semantic: true }toast()instead to provide the semantic model to a rule.export const rule = defineRule({query: semantic("JS_REFERENCE_IDENTIFIER"),run(node, { model }) {// Use `model` here.},});Becomes:
export const rule = defineRule({query: ast("JS_REFERENCE_IDENTIFIER", { semantic: true }),run(node, { model }) {// Use `model` here.},});This behaviour matches the
grit()query function, which also accepts the{ semantic: true }option. -
#12951
014b976Thanks @ematipico! - Fixed #10782:noUndeclaredClassesno longer appears to hang on projects with long component import chains. -
#13073
827e610Thanks @vibbix! - Fixed #13072: a comment before a SCSS map entry whose value is a parenthesized group no longer indents that group one level too deep. This matches Prettier 3.10 behavior now.$map: (/* comment */key: (a: 1,b: 2,),a: 1,b: 2,),); -
#12928
ae0e186Thanks @dyc3! - ImprovednoUselessStringConcat. The rule now reports literals joined after another value, such asfoo + "a" + "b", and fixes template literals with placeholders, so`Hello, ${name}` + "!"becomes`Hello, ${name}!`.The rule no longer reports strings that would join into text that looks like a placeholder, such as
"$" + "{name}", or into a directive such as"use strict". It also no longer reportsobj.foo * "a" + "b", which its fix used to change toobj.foo * "ab".The fix no longer changes the value of the string in two cases. It used to change
1 + 2 + "b" + "c"to"12bc"instead of1 + 2 + "bc". It used to change"\1" + "2"to"\12", which is a different escape sequence.The fix no longer joins literals that are on different lines when the concatenation ends with two literals on the same line. It also no longer puts a line break from a template literal into a string literal, which made the code invalid.
-
#13048
24734a8Thanks @ematipico! - Fixed #13028: Biome now keeps a paragraph in its outer block quote when a quote-only blank line closes a nested block quote.> > b>> > c> c -
#12967
bd0988eThanks @siketyan! - Fixed #12827:noDuplicateProperties,noDuplicateCustomProperties, andnoMissingVarFunctionnow check declarations at the top level of embedded CSS templates, such asstyled.div`...`. -
#13048
24734a8Thanks @ematipico! - Fixed #13029: the Markdown formatter now normalizes spaces inside inline and reference link text without removing whitespace-only text.something [ text ]( destination)something [ ]( destination)something [ text ](destination)something [ ](destination) -
#13021
05a1409Thanks @dyc3! - Fixed #12993: Svelte{@const}tags with TypeScript type annotations, such as{@const doubled: number = item * 2}, now parse and format in components with<script lang="ts">. -
#12968
ec0142bThanks @siketyan! - Fixed #12826: Biome now detects CSS in styled-components templates that use.attrs(), such asstyled.button.attrs({ type: "button" })`...`andstyled(Component).attrs(() => ({}))`...`, so they are formatted and linted likestyled.button`...`. -
#13048
24734a8Thanks @ematipico! - Fixed #13027: the Markdown formatter now preserves spaces around text after a code span that crosses block quote lines.> `a> b`c`d`> b` c `d` -
#13055
78c744aThanks @ematipico! - Fixed #13053: Biome now reports missing CLI paths as file-system errors without theINTERNALtag or advice that the path was ignored by configuration. File-system diagnostics now use specificfs/*categories, with underlying I/O errors categorized asfs/io. -
#12927
c6feec1Thanks @dyc3! - Added the nursery ruleuseCatchErrorName, which requires a specific name for caught errors intry...catchstatements and in the error handlers ofpromise.catch()andpromise.then(). The name defaults toerrorand can be changed with thenameoption.try {} catch (err) {} // `err` should be named `error` -
#12788
7f971edThanks @dyc3! - ExtendeduseWhileto reportfor (;;)loops and to fix them towhile (true). -
#12967
bd0988eThanks @siketyan! - FixednoMissingVarFunctionso it also checks declarations inside at-rules such as@pageand@font-face. For example,@page { margin: --page-margin; }is now reported when--page-marginis declared in:root. -
#13057
d9267a5Thanks @ematipico! - Fixed #10896 so Svelte<script generics>attributes containing object type constraints parse and format as TypeScript type parameters. -
#13048
24734a8Thanks @ematipico! - Fixed #13038: Biome now aligns wrapped task-list paragraphs with the text following the checkbox.- [ ] Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc variusmalesuada eros, faucibus dapibus odio rhoncus in.malesuada eros, faucibus dapibus odio rhoncus in.
Copyright (c) 2023-present Biome Developers and Contributors.