@biomejs/biome
- 2.5.15 is the latest, published 30 September 2026.
- No known security advisory.
- 2.x: 68 releases since 17 June 2025, 11 in the last 90 days.
Releases in the last 90 days
Feed of releases and advisoriesEvery stable release, newest first. Notes are quoted as the maintainers published them.
2.5.15
30 September 2026Added the new nursery rule noReactObjectTypeAsDefaultProp, which disallows array, object, and function values as default props in React components.For example, the following snippet triggers the rule.function Component({ items = [] }) {
Patch Changes
Added the new nursery rule
noReactObjectTypeAsDefaultProp, which disallows array, object, and function values as default props in React components.For example, the following snippet triggers the rule.
function Component({ items = [] }) { return items; }Added the nursery rule
noSvelteExportLet, which disallows declaring Svelte component props with the legacyexport letsyntax. Use the$props()rune instead.<script> export let name; </script>
Added a new nursery rule
useLogicalPropertiesthat enforces the use of logical properties in CSS, promoting better internationalization and accessibility practices. The rule supports adirectionoption with"ltr"as the default and"rtl"as the alternative. This is a first rule covering parts of #9034{ "linter": { "rules": { "nursery": { "useLogicalProperties": { "level": "warn", "options": { "direction": "rtl" } } } } } }Added the nursery rule
useSvelteKitRuneImports, which reports imports from the deprecated$app/storesmodule and suggests$app/stateinstead.import { page } from "$app/stores";Fixed #11656:
noAstroSetHtmlDirectivenow correctly reportsset:htmldirectives inside Astro template expressions.Improved the performance of the HTML formatter up to 4x.
Fixed #11351:
useSimplifiedLogicExpressionno longer reports boolean literals on the right side of||and&&outside boolean contexts, because removing them can change the result of the expression. For example,y = x || falseis no longer reported, whileif (x || false)still is.Added the nursery rule
noMeaninglessVoidOperator, which reports unnecessary uses ofvoid, such asvoid log()whenlogreturnsvoid. The rule allows discarded call results, thenables,void 0, and calls returningnever.Fixed the indentation of multiline Astro expressions, in templates and attribute values, when running
biome check --write. Biome now formats Astro expressions withbiome formattoo, and places them at the column of the surrounding markup.<div> {items.map((item) => ( - <span>{item}</span> -))} + <span>{item}</span> + ))} </div>Improved the performance of indexing and analysis of big files up to 2x. The improvements are mostly visible in projects that make use of project and types lint rules.
Added the nursery rule
useStrictBooleanExpressions, which reports ambiguous truthiness checks such asif (value)whenvaluehas typenumber | undefined. Non-nullable strings and numbers and nullable objects are allowed; the rule has no options.Added the nursery rule
noAstroConflictingSetDirectives, which reports Astro elements with multiple content sources, such asset:html,set:text, and child content.For example,
<div set:html={html}>content</div>triggers the rule.Fixed #11748:
useExhaustiveSwitchCasesnow reports missing cases for values created with the mapping overload ofArray.from, including arrays imported from another module.Tailwind classes will now be detected in Svelte, Vue, and Astro class attribute expressions that don't use a class merging function.
Fixed #11504, a regression where Biome would silently ignore errors in the configuration file. Now errors are correctly retained and checked before executing any command.
Fixed #10846: when plugins fail to load, Biome now prints each failing plugin's path on its own line, instead of concatenating bare messages like
Cannot read file.Cannot read file..[
82ea5a6](github.com/biomejs/biome/commit/82ea5a
2.5.14
16 September 2026Added the nursery rule noReturnInFinally. This rule disallows return statements in Promise.prototype.finally() callbacks, including inside nested blocks and conditional branches. Returns in nested functions are ignored by the rule.// Invalid: return in finally callback
Patch Changes
Added the nursery rule
noReturnInFinally. This rule disallows return statements inPromise.prototype.finally()callbacks, including inside nested blocks and conditional branches. Returns in nested functions are ignored by the rule.// Invalid: return in finally callback Promise.resolve(1).finally(() => { return 2 }) // Valid: no return in finally callback Promise.resolve(1).finally(() => { console.log(2) })Returning a value from a
Promise.prototype.finally()callback does not replace the original promise's fulfillment value, which can be confusing. Returned promises and thenables are awaited, and their rejection rejects the resulting promise.Added the nursery rule
noSvelteAtDebugTags, which disallows Svelte's{@debug}tag.<!-- Invalid: leftover debugging tag --> {@debug user}The
{@debug}tag is a debugging aid and should be removed once you no longer need it, as it should not remain in production code. The rule provides a safe fix that removes the tag.Added the nursery rule
useValidTestTitle, which enforces valid titles for unit test cases and suites.Fixed #8471:
source.fixAll.biomeignoredformatter.formatWithErrors. It now applies safe fixes without formatting files that have parse errors when the option is disabled.Fixed #7771: Grit plugins that use
sequentialno longer panic when Biome processes files.Fixed validation of
readonlyandaccessormodifiers: combining them in either order now reports that they cannot be used together.Fixed #11423: Multiline template interpolations now preserve the indentation of their closing brace when the source indentation is not a multiple of
tabWidth.const value = ` ${ condition ? "yes" : "no" -} + } `;Fixed #11763: TypeScript class members using
override accessor, such asoverride accessor value = 1, now parse correctly. The reversed order,accessor override, now reports thatoverridemust precedeaccessor.Fixed #10248:
noUselessFragmentsnow allows fragments with props in Astro files, such as<Fragment slot="name">{text}</Fragment>inside template expressions.Fixed #7573: added the
requireExplicitCaseoption touseExhaustiveSwitchCases. When set totrue, the rule reports missing cases even when the switch has adefaultclause, so you can keep a runtime fallback while checking that every value in the union has its own case. The option defaults tofalse.Fixed #8347: the fix from
useConsistentArrowReturnnow parenthesizes returned expressions that begin with object literals before removing the arrow function body braces, preventing invalid output for expressions such as object property access.Fixed #11782:
noUndeclaredCustomPropertiescould hang while checking stylesheets imported by JavaScript modules with many shared dependencies.Fixed #7984: The fix from
useSimplifiedLogicExpressionnow preserves line breaks in multiline conditions with line comments, preventing the right-hand side condition from being commented out.Fixed #7304: the HTML formatter now preserves authored segment breaks between CJK characters, and next to CJK punctuation, instead of replacing them with spaces.
<div lang="zh-Hant-TW"> - 這個段落是那麼長, 在一行寫不行。 + 這個段落是那麼長, + 在一行寫不行。 </div>
Fixed #11747: formatting and checking large parenthesized object expressions no longer exhibit quadratic slowdowns.
Fixed #8177: code actions no longer modify the wrong part of Vue, Svelte, or Astro files when experimental full HTML support is disabled.
[#11743](github.com/bi
2.5.13
10 September 2026Added the nursery rule useLayeredStyles, which enforces that style rules are defined within a cascade layer and import rules to import its styles into a cascade layer./* Invalid */
Patch Changes
Added the nursery rule
useLayeredStyles, which enforces that style rules are defined within a cascade layer and import rules to import its styles into a cascade layer./* Invalid */ @import 'foo.css'; .my-style { color: red; } /* Valid */ @import 'foo.css' layer(base); @layer base { .my-style { color: red; } }Added the nursery rule
useBetterDomTraversing, which prefers.firstChild,.firstElementChild,.closest(), and merged.querySelector()calls over positional DOM traversal.element.childNodes[0]; element.children[0]; element.parentElement.parentElement; element.querySelector("a").querySelector("b");Fixed #11610, #11611, #11612, #11615, and #11616: Biome no longer fully infers an imported generic declaration just to apply its type arguments, restoring type-aware lint performance for large libraries such as Zod. This improves
useRegexpExec,noFloatingPromises,noMisusedPromises,useNullishCoalescing, andnoUnsafePlusOperands.Fixed #7495:
noUselessConstructornow ignores TypeScript constructors that forward at least one argument tosuper, preserving constructors that narrow the subclass's accepted parameter types. The exemption also applies when the parent and child signatures are identical; JavaScript and zero-argument forwarding behavior are unchanged.Fixed #7076:
useAriaPropsForRoleanduseFocusableInteractiveno longer report non-focusable elements withrole="separator". A separator with an explicittabIndexortabindexstill requiresaria-valuenow.Fixed #6571 so Grit plugins can capture and inspect multiple named import specifiers.
Reduced unnecessary type inference when type-aware lint rules inspect members of namespace imports from libraries such as Zod. Fixed type inference so blanket re-exports do not expose default exports.
Added the nursery rule
noXorAsExponentiation, which reports the bitwise XOR operator^between two decimal integer literals, where the exponentiation operator**was likely intended.const kibibyte = 2 ^ 10; // 8, not 1024
Fixed #7192:
noUnusedPrivateClassMembersnow considers compound assignments such as??=to read and use private class members.Fixed #11672 and #11671 by disabling the experimental capitalized-call and effect-dependency checks in
useReactCompiler, matching their exclusion from upstream's recommended lint preset. Valid calls such asIntl.NumberFormat()and captures of variables declared inside effects no longer produce these diagnostics.Fixed #11653: Astro template suppression comments (
{/* biome-ignore lint: reason */}) now suppress matching HTML lint diagnostics on the following line when full HTML support is enabled.Improved the performance of
useRegexpExec.Fixed #7479.
noUnusedVariablesnow treats Unicode escapes in identifiers as the same binding as their decoded spelling.Fixed the HTML formatter inserting whitespace between adjacent Svelte expressions when their combined length exceeds the line width.
<span> - {head.median - base.median >= 0 ? "+" : "−"} - {formatMs(Math.abs(head.median - base.median))} + {head.median - base.median >= 0 ? "+" : "−"}{formatMs(Math.abs(head.median - base.median))} </span>Fixed #11644: [
useHeadingContent](biomejs.dev/lint
2.5.12
3 September 2026Fixed Astro attribute expressions rejecting TypeScript and JSX syntax that is accepted in text expressions.<Component icon={<Icon />} count={total as number} onSelect={(e: Event) => e} />
Patch Changes
Fixed Astro attribute expressions rejecting TypeScript and JSX syntax that is accepted in text expressions.
<Component icon={<Icon />} count={total as number} onSelect={(e: Event) => e} />Fixed Astro attribute names being split on
:and.inside an expression, such as{x && <button x-on:keyup.enter={go} client:load.foo />}.Fixed a bare
>in the children of an Astro expression being treated as markup, such as{x && <div>a > b</div>}.Fixed HTML comments inside an Astro expression failing to parse. They are now read as trivia, wherever they appear among the children.
{x && <div><!-- first -->text<!-- last --></div>} {cond && <a></a><!-- c --><b></b>}Fixed
is:rawchildren inside an Astro expression being read as JSX, such as{x && <div is:raw>{not js} < & text</div>}.Fixed an apostrophe or quote in the text of a JSX element inside an Astro expression ending the expression early, such as
{items.map((i) => <li>it's {i}</li>)}.Fixed the children of a
<script>or<style>inside an Astro expression being read as JSX. Their contents are text, so braces and comparisons no longer have to be escaped.{cond && <style>a { color: red }</style>} {cond && <script>let x = {a: 1};</script>}Added support for template literal attribute values inside an Astro expression, such as
{x && <C data-x=`t${x}` />}.Fixed unquoted attribute values being rejected inside an Astro expression, such as
{x && <a class=foo maxlength=255 href=/about>go</a>}.Fixed a template literal nested inside
${}breaking the rest of an Astro file, such asconst href = `/blog${page === 0 ? '' : `/${page + 1}`}`;.Fixed a quote inside a regex character class breaking the rest of an Astro file, such as
const unsafe = /[/"]/;.Added the nursery rule
useFlatMathMinMax. BecauseMath.min()andMath.max()accept any number of arguments, the rule reports unnecessary nested calls to the same method:Math.max(Math.max(a, b), c);
The fix flattens this expression to
Math.max(a, b, c).Fixed #11475:
noUnresolvedImportsno longer reports Bun runtime built-in modules (bun,bun:bundle,bun:ffi,bun:jsc,bun:sqlite,bun:test).Fixed #6830: Biome now reports a diagnostic for excessively deep syntax instead of overflowing the native stack while releasing the parsed tree.
Added the nursery rule
noThisOutsideOfClass. The rule reportsthisoutside class members and TypeScript functions with an explicitthisparameter.function Person(name) { this.name = name; }Fixed #11529, where
noFloatingPromisesmissed unhandled Promise chains when the imported function's module belonged to an import cycle. Cyclic modules now preserve types for exports that do not participate in recursive type dependencies.Fixed #11500: the formatter now prints the
declaremodifier before accessibility modifiers on class properties.private declare readonly name: stringis now formatted asdeclare private readonly name: string, matching Prettier and TypeScript's canonical modifier order.Fixed #5091: Biome no longer moves comments next to the
<of a generic, which causes invalid TypeScript syntax:- Generic<// a comment + Generic< + // a comment
Fixed #4592. Biome no longer crashes while parsing malformed
deleteexpressions.F
2.5.11
27 August 2026Fixed #11496: useValidAnchor now treats Astro JSX shorthand attributes like as a valid href.
Patch Changes
Fixed #11496:
useValidAnchornow treats Astro JSX shorthand attributes like<a {href}>as a validhref.Fixed #9944: adjacent elements inside an Astro expression now parse as an implicit fragment instead of raising an error.
{options.map(() => <div /> <div /> )}Fixed Astro templates rejecting unclosed HTML void elements, such as
{cond && <br>}.Fixed #11157:
noUnusedVariablesno longer reports Vue<script setup>bindings used by CSSv-bind()as unused.Fixed #11389: Files passed through
--stdin-file-pathnow use full HTML support for Astro, Svelte, and Vue when it is enabled.Fixed
noVueRefAsOperandto track Vue refs through declaration aliases andtoRefs()properties, and to recognizeuseTemplateRef()results. The rule no longer reports false positives such as plain ref transfers, plaintoRefs()property access,defineModel()modifiers, or the supported.effectmember as operands.The refactor enabling these fixes also improves the performance of the rule.
Fixed #11436: GritQL snippets such as
export { $specifiers } from $sourcenow match named re-exports with aliases, inlinetypemodifiers, and multiple specifiers.Fixed #11390, where
noFloatingPromisesperformed expensive full type inference for calls to non-Promise methods declared on third-party TypeScript classes. The rule now classifies those calls using targeted type information.Fixed
noVueRefAsOperandso it no longer reports a callback parameter (e.g. from.find(),.map()) as an unwrapped ref value just because it's nested inside aref(),computed(), or similar call.const result = computed(() => list.find((item) => item.label === "a"));
Previously,
itemhere was incorrectly treated as a ref value because the rule attributed it to the outercomputed()call.Fixed
useGraphqlNamingConventionso it no longer reports GraphQL enum value definitions with comments & descriptions and now displays a more accurate diagnostic range.Fixed #11214:
noUnusedVariablesno longer reports type parameters declared by non-default function overload signatures that have an implementation.- security
Added a new nursery rule
noAstroSetHtmlDirective, which disallows Astro'sset:htmldirective because untrusted content can introduce cross-site scripting vulnerabilities.For example, the following snippet triggers the rule:
<div set:html={content} /> Fixed #10776:
useVueHyphenatedAttributesno longer reports lowercase attribute names containing punctuation, such aspt:header:data-test-idandsome_attr.Fixed #10330: Vue interpolation delimiters now stay attached to whitespace-sensitive element boundaries and adjacent inline siblings, wrapping their expression when needed to fit the configured line width. Interpolations followed by text now also converge after one formatting pass.
-<v-btn v-if="store.state.user" variant="text" to="/my-rooms" - >{{ $t("nav.my-rooms") }}</v-btn -> +<v-btn v-if="store.state.user" variant="text" to="/my-rooms">{{ + $t("nav.my-rooms") +}}</v-btn>Added the nursery rule
noUndeclaredCustomProperties, which reports references to custom properties that are not defined in available CSS, static HTML-likestyleattributes, or JSX stringstyleattributes.For example, the following snippet triggers the rule:
a { color: var(--undefined-color); }Fixed: Variables and imports used as custom Vue directives are no longer reported as unused.
For example:
<script setup> const vHighlight = { mounted: (element) => { element.style.color = "red"; }, }; </script> <template> <p v-highlight>Hello</p> </template>[
e6acded](github.com/b
2.5.10
21 August 2026Fixed Astro rejecting JavaScript comments between attributes.
Patch Changes
Fixed Astro rejecting JavaScript comments between attributes.
<div /* block comment */ class="something"></div> <Component /* c */ client:load />
Fixed a bare
<in Astro text being treated as the start of a tag, such as<p>5 < 6 and 7 > 6</p>. As in HTML, a<that cannot open a tag is text and needs no escaping.Fixed #8294: an Astro expression holding only a comment is no longer reported as a parse error, which also stopped the whole file from being formatted.
<div>{/* a note */}</div> <div class={/* a note */}>x</div>Fixed #9165: an empty Astro expression such as
<div>{}</div>no longer fails to parse. Astro renders{}as nothing.Fixed Astro expressions containing a comment failing to parse.
<div>{/* block comment */ x}</div> <div>{/* only a comment */}</div>Added support for Astro's fragment shorthand.
<> <p>a</p> </>
Fixed an Astro frontmatter block being cut short by a closing tag inside a string or comment.
--- const a = "</script>"; // </script> in a comment ---
Fixed
---being read as an Astro frontmatter fence when markup precedes it. Astro only recognizes frontmatter at the very start of a file, so a file opening with a comment now has no frontmatter, and its---lines are content.<!-- c --> --- this is text, not frontmatter ---
Fixed an Astro frontmatter block ending early on a line that merely starts with a dash.
--- --count; ---
Fixed the children of an Astro element carrying
is:rawbeing parsed as markup instead of raw text. This now also covers<script>and<style>, whose contents Astro emits verbatim rather than processing, so they are no longer linted as JavaScript or CSS.<article is:raw><% awesome %></article> <script is:raw>{{ mustache }}</script>Fixed Astro rejecting attribute names that start with a colon, such as
:href.Fixed the Astro parser failing to recover from a malformed closing tag such as
<div></{<//, so that a later mistake is reported where it happens rather than cascading.Fixed
{inside an Astro<math>element opening an expression. MathML is foreign content where Astro parses no expressions, so LaTeX such asR^{2x}now survives as text.<svg>is unaffected.Fixed
{{at the start of an Astro expression being read as an interpolation. Astro has no{{ }}syntax, so{{ a: 1 }}and<Comp a={{ b: 1 }} />are object literals.Fixed expressions inside an Astro
<pre>or<textarea>being read as raw text. Astro parses both as ordinary elements, so their markup and interpolations are now parsed, and a variable used only inside one is no longer reported as unused.<pre>{value}</pre> <textarea><div>{value}</div></textarea>Added support for template literal attribute values in Astro, such as
<div class=`a ${b} c`>.Fixed Astro rejecting HTML5 unquoted attribute values that contain
`,=,'or", such as<a href=a=b>and<a href=a'b>.Fixed #11207:
useStrictModeno longer reports Vue event handlers such as@click="count++".Fixed #11429: Variables and imports used by Vue same-name bindings such as
:disabledorv-bind:disabledare no longer reported as unused.Fixed a memory leak in the LSP server where memory usage kept growing over long editor sessions.
Thanks
2.5.9
17 August 2026Fixed #11315: The CSS parser now recovers at declaration boundaries after bogus declarations, allowing subsequent valid declarations to be parsed.
Patch Changes
Fixed #11315: The CSS parser now recovers at declaration boundaries after bogus declarations, allowing subsequent valid declarations to be parsed.
Expanded the environment variable metadata used by
biome rageto includeBIOME_BINARY,BIOME_LOG_FILE, andRUST_BACKTRACEas well as reworded explanations for better readability.Added a new nursery rule
useNamedLayerwhich disallows anonymous cascade layers.@layer { a { color: red; } }The HTML formatter now preserves meaningful blank lines in HTML, including spacing after elements with trailing spaces and blank lines between comment groups.
<div> <!-- first group --> + <!-- second group --> </div>
Added the nursery rule
useTailwindShorthandClasses, which suggests shorter Tailwind utility classes. For example, the rule suggests replacingw-4 h-4withsize-4.Fixed #11328:
lint/nursery/useExpectnow recognizes Vitest Browser Modeexpect.element()calls as assertions.Fixed #11311: the CSS parser now accepts Tailwind container-query variant names in
@variant, such as@xland@max-xl. These previously produced a parse error and anoUnknownAtRulesdiagnostic.@variant @xl { div { background: red; } }Fixed #9541:
noUndeclaredVariables,noUnusedImports, andnoUnusedVariablesnow correctly recognise exported variables and functions declared in one embedded<script>block as usable from a sibling<script>block, in Svelte's<script module>/<script>pair and Vue's non-setup<script>blocks.For example, Biome no longer reports
greetas undeclared in the following Svelte component:<script module> export function greet() { console.log("Hello!"); } </script> <script> greet(); </script>Fixed the HTML formatter's whitespace handling for
marquee,noscript,video,audio, andobjectelements.- <marquee behavior="alternate"> This text will bounce </marquee> + <marquee behavior="alternate">This text will bounce</marquee>
Added the nursery rule
useAstroClientOnlyDirectiveValue, which reports Astroclient:onlydirectives without an initializer.For example,
<Component client:only />triggers the rule.Fixed #11229: The
useGenericFontNamesrule now treatsmathas a valid generic font family.Fixed #11335:
noComponentHookFactoriesnow reports ause-prefixed variable only when a function is assigned to it directly.function factory() { const useColors = true; // no longer reported const useStore = createStore({ count: 0 }); // no longer reported const useData = () => useState(null); // still reported return useColors; }Fixed #11317:
noSvgWithoutTitleno longer reports ansvgthat uses the boolean shorthandaria-hidden(equivalent toaria-hidden={true}in React).Fixed a bug where
useJsxKeyInIterableincorrectly flagged Astro files.Fixed #11315: Invalid CSS declarations in HTML
styleattributes now produce parser diagnostics instead of causing a panic.Fixed HTML text wrapping to account for the width of an adjacent closing tag, avoiding lines that exceed the configured width when the final word and tag must move together.
<a-long-long-long-element - >foo bar foo bar foo bar foo bar foo bar foo bar foo bar</a-long-long-long-element + >foo bar foo bar foo bar foo bar foo bar foo + bar</a-long-long-long-element >
Fixed TypeScript
compilerOptions.pathsresoluti
2.5.8
11 August 2026Added a new nursery rule useReactCompiler, which reports diagnostics from React Compiler lint mode.
Patch Changes
Added a new nursery rule
useReactCompiler, which reports diagnostics from React Compiler lint mode.Improved performance of
noImportCycles.Added the nursery rule
noSvelteLegacyConst, which disallows legacy Svelte{@const}tags and recommends declaration tags with$derived().Invalid:
{#each boxes as box} {@const area = box.width * box.height} <p>{area}</p> {/each}Valid:
{#each boxes as box} {const area = $derived(box.width * box.height)} <p>{area}</p> {/each}Fixed #11250:
useAwaitno longer reports async functions that contain anawait usingdeclaration.Fixed #11017:
noUselessUndefinedno longer reportsreturn undefinedwhen the enclosing function has a return type annotation other thanundefinedorvoid.Fixed #11228: CSS block comments between a declaration colon and value now preserve their source indentation.
:root { --font-stack: -/* comment */ + /* comment */ system-ui; }Fixed #11280: CSS formatting keeps comments inside functional pseudo-classes and pseudo-elements instead of moving them before the function name.
-:/* comment */ where(div) {} +:where(/* comment */ div) {}HTML
styleattribute values are now parsed as CSS. All Biome CSS lint rules are applied to thestyleattributes.Fixed Svelte files failing to parse when an expression begins with an object literal.
Now the following snippet is correctly parsed:
<p>{{ a: true }}</p> <div class={{ active: isActive }}></div>Fixed #10242: JavaScript GritQL patterns with multiple metavariables now match snippets consistently in WebAssembly.
Added the nursery rule
noInvalidPropertyInitValue, which reports an@propertywhoseinitial-valuedoes not match itssyntaxdescriptor. For example, the following declaration triggers the rule becauseredis not a<length>:@property --size { syntax: "<length>"; inherits: false; initial-value: red; }Improved the diagnostic emitted by
noRootType.Fixed #11223: Improved the performance of
noMisusedPromiseswhen analyzing async class methods that call other methods throughthis.Fixed #10806:
noUselessFragmentsno longer causes Biome to panic when its unsafe fix removes a fragment used as a JSX attribute value.Fixed #11178:
noUndeclaredVariablesno longer reports Vue's built-in instance properties, such as$slotsand$attrs, in template expressions or$eventin inline event-handler expressions. The instance properties are still reported inside<script setup>, where they are not defined.Fixed CSS parsing of registered custom properties: Biome now correctly validates the
syntaxdescriptor of@propertyrules.
What's Changed
feat(service): treat html style attributes as CSS
feat: code review skill
fix(lint/noUselessFragments): panic when fixing a fragment used as a JSX attribute value
feat(lint/js): add
useReactCompilerfix(inference): query local types before global
feat(lint/html): add `noSvel
2.5.7
4 August 2026Added the option ignoreIfStatements to useNullishCoalescing. Biome now flags if statements that only assign to a nullish variable (such as if (!a) { a = b }) and can rewrite them to ??=. When enabled, Biome ignores those if statements.
Patch Changes
Added the option
ignoreIfStatementsto useNullishCoalescing. Biome now flagsifstatements that only assign to a nullish variable (such asif (!a) { a = b }) and can rewrite them to??=. When enabled, Biome ignores thoseifstatements.Added a new nursery rule
noExtendNative, which reports extending the prototype of a built-in object.Added the nursery rule
noTailwindArbitraryValue. Biome now reports Tailwind CSS arbitrary values such asw-[400px], including in HTML/JSX class attributes, configured utility functions, and tagged templates.Fixed #11176:
noUnknownPseudoClassnow recognizes Vue's:deep()pseudo-class inside.vuestyle blocks.Fixed #8233, where Biome CLI in stdin mode didn't work correctly when handling files in projects with nested configurations. For example, with the following structure,
--stdin-file-path=subdirectory/...would not use the nested configuration insubdirectory/biome.json:├── biome.json └── subdirectory ├── biome.json └── lib.jsbiome format --write --stdin-file-path=subdirectory/lib.js < subdirectory/lib.js
Now, the nested configuration is correctly picked up and applied.
In addition, Biome now shows a warning if
--stdin-file-pathis provided but that path is ignored and therefore not formatted or fixed.Fixed
noUnnecessaryConditions: Biome now chooses the same function overload as TypeScript when an argument is a callback, so conditions that were previously missed are reported.The following code is now invalid, because a parameter typed
() => voidaccepts anasynccallback andscheduletherefore returnsstring:declare function schedule(handler: () => void): string; declare function schedule(handler: () => Promise<void>): string | undefined; schedule(async () => {}) ?? "fallback";The following code is also now invalid, because
map(() => 42)returns42:type Mapper<T> = () => T; declare function map<T>(mapper: Mapper<T>): T; map(() => 42) || flag;
Fixed #11087:
noUnnecessaryConditionsno longer reports optional chains and nullish coalescing whose receiver can be nullish.For example, the optional chain and fallback in the following code are no longer reported:
declare const usage: { range: { startDate: string } } | null; const startDate = usage?.range.startDate ?? "N/A";Fixed #11098: The HTML formatter now preserves the configured trailing newline when a file ends with a comment.
-<!-- trailing comment --> \ No newline at end of file +<!-- trailing comment -->
Fixed #11182: suppression comments for
noPositiveTabindexnow suppress the rule in HTML files when the attributes of the element span multiple lines.The HTML formatter now lays out the
srcsetattribute of<img>and<source>as the list of candidates it is. Runs of whitespace between candidates collapse, and once the list no longer fits on one line each candidate goes on its own line with the descriptors aligned:- <img srcset="/visual@0.5.png 400w, /visual.png 805w, /visual@2x.png 1610w, /visual@3x.png 2415w" /> + <img + srcset=" + /visual@0.5.png 400w, + /visual.png 805w, + /visual@2x.png 1610w, + /visual@3x.png 2415w + " + />
Fixed #11129:
noUnusedVariablesno longer reports Vue bindings as unused when they are assigned through automatically unwrapped template refs.Fixed CSS formatting of line comments between a declaration colon and value to preserve their source indentation.
.test { background: - /////// foo - // bar + /////// foo + // bar radial-gradient(circle, #000, transparent); }Fixed CSS formatting of long block comments between comma-separated property values:
.foo { box-shadow: - 1000px /* long long long long long long long long long long long long comment */ 1000px /* long long long long long long long long long comment */ 2px color(srgb 0.555555555 0.555555555 0.555555555), + 1000px + /* long long long long long long long long long long long long comment */ + 1000px /* long long long long long long long long long comment */ 2px + color(srgb 0.555555555 0.555555555 0.555555555), 1px 1px black; }The HTML formatter now pi
2.5.6
28 July 2026Fixed a performance regression in noMisusedPromises that caused type inference to run repeatedly while linting a file.
Patch Changes
Fixed a performance regression in
noMisusedPromisesthat caused type inference to run repeatedly while linting a file.Fixed CSS formatting for multiline function arguments preceded by comments:
.example { value: outer( 1, /* comment */ nested( - first, - second - ) + first, + second + ) ); }Fixed #9195:
useHookAtTopLevelno longer reports hooks in namedforwardRefcomponents that receive arefparameter.Fixed #10131: Biome now correctly parses curried arrow functions in ternary consequents when the inner arrow's parameters use a destructuring pattern, e.g.
cond ? (x) => ({ a, b }) => body : alt.Fixed #11092: The
noUselessTernaryquick fix now preserves operator spacing when simplifying or inverting boolean ternary expressions.Fixed #10515:
biome check --writewas not idempotent on Svelte files — multi-line template literals in<script>blocks and block comments in<style>blocks gained an extra indent level on every run.Fixed an issue where the HTML formatter would duplicate a comment placed directly before a Svelte
{@const ...}or{@debug ...}block. The duplication compounded on every subsequent--write, causing the file to grow exponentially.Fixed #10839: Svelte
{#each}array destructuring no longer includes spaces inside square brackets, and multiline bind function expressions now indent their getter, setter, and function body correctly.Improved the accuracy of type-aware lint rules by resolving more inferred types. For example,
noFloatingPromisesnow detects floating Promises returned by aliased callbacks and arrays of Promises created by async mapping callbacks.The following statements are now reported:
type AsyncCallback = () => Promise<void>; declare const callback: AsyncCallback; callback(); [1, 2, 3].map(async (value) => value);
Fixed false positives in
noMisleadingReturnTypewhen generic-constraint, normalization, substitution, or structural return-type comparison cannot complete. The rule now suppresses diagnostics rather than suggesting a return type derived from partial information. For example, this unresolved return type is no longer reported:function unresolvedReturnType(): MissingType { return "value" as const; }The HTML parser now accepts mixed-case
doctypedeclarations.The
rdjsonreporter now populates the severity field of each diagnostic (ERROR,WARNING, orINFO), so tools consuming Reviewdog Diagnostic Format output no longer need to assume a default severity.Fixed a performance regression in type-aware JavaScript lint rules by inferring only requested types and memoizing export resolution.
Added support for Svelte declaration tags using
letandconst. Biome can now parse, format, and lint bindings declared in these tags.Improved the performance of Biome formatter up to ~7% across the board.
Added the nursery rule
noJsRestrictedProperties, which ports ESLint'sno-restricted-propertiesrule. Biome now flags restricted member access and object destructuring, andbiome migrate eslintpreserves the rule's options.
What's Changed
fix(linter): recognize forwardRef named components with ref params
fix(html_formatter): match prettier for svelte each as destructuring …
fix(cli): populate severity in rdjson reporter output
Show 1 earlier releases
2.5.5
21 July 2026Fixed useExhaustiveSwitchCases for unions of bigint literals. The rule now reports missing bigint cases and compares bigint literals by value, including binary, octal, hexadecimal, and separator-containing spellings. For example, this switch now reports the missing 2n case:declare const value: 1n | 2n;
Patch Changes
Fixed
useExhaustiveSwitchCasesfor unions of bigint literals. The rule now reports missing bigint cases and compares bigint literals by value, including binary, octal, hexadecimal, and separator-containing spellings. For example, this switch now reports the missing2ncase:declare const value: 1n | 2n; switch (value) { case 1n: break; }Fixed false positives in
noBaseToStringanduseNullishCoalescingwhen member, stringification, or nullish inference cannot complete. These rules now suppress diagnostics instead of reporting from partial type information. For example, neither expression is reported when a recursive type cannot be fully resolved:type Recursive = Recursive; declare const value: Recursive; String(value); value || "fallback";
Fixed #10922: the action
useSortedAttributesno longer triggers for HTML instructions.Fixed
noThenPropertyfailing to detectObject.fromEntries,Object.defineProperty, andReflect.definePropertycalls with comments between their tokens.Fixed #10980:
useAriaPropsSupportedByRoleno longer reports false positives when the attribute that determines an element's implicit ARIA role is written as a shorthand attribute, such as<a {href} aria-label="...">in Astro and Svelte files.Shorthand attributes are now taken into account when computing the implicit role, so the anchor above correctly resolves to the
linkrole instead ofgeneric.Fixed CSS formatter casing for syntax-owned names while preserving author-defined names, including scoped keyframes and container scroll-state queries.
- A:HOVER { COLOR: INITIAL; } + A:hover { color: initial; } - @KEYFRAMES :GLOBAL KeepFrames { FROM { COLOR: RED; } } + @keyframes :GLOBAL KeepFrames { from { color: RED; } } - @CONTAINER scroll-state((SCROLLED: TOP) AND (STUCK)) { A:HOVER { COLOR: RED; } } + @container scroll-state((SCROLLED: TOP) AND (STUCK)) { A:hover { color: RED; } }Fixed CSS formatting for comments between declaration values and
!important.-a { color: /* before */ /* after */ red !important; } +a { color: /* before */ red /* after */ !important; }Fixed the CSS formatter to preserve comments on the correct side of selector combinators and before declaration blocks.
-.before > /* comment */ .after {} +.before /* comment */ > .after {}It now also keeps selectors with escaped newlines in attribute values inline when they fit.
-div - span[foo="bar\ +div span[foo="bar\ value"] {}Fixed #10870:
noUnresolvedImportsno longer reports false positives such asimport type { NextRequest } from "next/server".Fixed #10622: the HTML/Vue parser no longer panics on the argument-less
v-bindshorthand (:="props").This syntax is valid Vue and equivalent to
v-bind="props", so the parser now accepts it (along with the longhandv-bind:="props") instead of crashing while building a diagnostic for a missing argument.Improved generic tuple inference for
useIncludes. The rule now recognizes specialised tuple element types returned through generic aliases.Fixed
#10855: Biome now supports parsing and formatting CSS custom media queries declared with@custom-media.Fixed an issue where Biome logs became too verbose, dumping information not relevant to user's operations.
Fixed #10963: Biome no longer panics when a type-aware rule such as
noFloatingPromiseschecks a call to a function with multiple call signatures imported from another module.Fixed
check --writecommand. Now the command reports code frame of the formatted code, if the formatter is enabled.Fixed #10892: [
noUnnecessaryConditions](biomejs.dev/linter/rules/no-unnecessary-conditi…
Major versions
- 2.xsince 17 June 2025 · latest 2.5.15 · 68 releases
- 1.xsince 28 August 2023 · latest 1.9.4 · 35 releases
- 0.xsince 18 August 2023 · latest 0.2.3 · 4 releases
Quality and security signals
What npm and deps.dev say about the latest release. Signals, not a verdict.
Reading npm and deps.dev…
Registry facts last checked 15 October 2026. Releases and advisories last read 14 October 2026.
Know when your own dependencies move
Inlinr tracks your coding time automatically. Switch dependency tracking on for a project and it reads that repository's manifest to show what is behind and what has been deprecated — off by default, one project at a time.