Packages

@biomejs/biome

2.5.15MIT OR Apache-2.0
  • 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 advisories

Every stable release, newest first. Notes are quoted as the maintainers published them.

  1. 2.5.15

    30 September 2026
    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 = [] }) {

    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 legacy export let syntax. Use the $props() rune instead.

      <script>
        export let name;
      </script>
    • Added a new nursery rule useLogicalProperties that enforces the use of logical properties in CSS, promoting better internationalization and accessibility practices. The rule supports a direction option 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/stores module and suggests $app/state instead.

      import { page } from "$app/stores";
    • Fixed #11656: noAstroSetHtmlDirective now correctly reports set:html directives inside Astro template expressions.

    • Improved the performance of the HTML formatter up to 4x.

    • Fixed #11351: useSimplifiedLogicExpression no 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 || false is no longer reported, while if (x || false) still is.

    • Added the nursery rule noMeaninglessVoidOperator, which reports unnecessary uses of void, such as void log() when log returns void. The rule allows discarded call results, thenables, void 0, and calls returning never.

    • Fixed the indentation of multiline Astro expressions, in templates and attribute values, when running biome check --write. Biome now formats Astro expressions with biome format too, 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 as if (value) when value has type number | 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 as set:html, set:text, and child content.

      For example, <div set:html={html}>content</div> triggers the rule.

    • Fixed #11748: useExhaustiveSwitchCases now reports missing cases for values created with the mapping overload of Array.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. 2.5.14

    16 September 2026
    Added 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 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
      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.biome ignored formatter.formatWithErrors. It now applies safe fixes without formatting files that have parse errors when the option is disabled.

    • Fixed #7771: Grit plugins that use sequential no longer panic when Biome processes files.

    • Fixed validation of readonly and accessor modifiers: 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 as override accessor value = 1, now parse correctly. The reversed order, accessor override, now reports that override must precede accessor.

    • Fixed #10248: noUselessFragments now allows fragments with props in Astro files, such as <Fragment slot="name">{text}</Fragment> inside template expressions.

    • Fixed #7573: added the requireExplicitCase option to useExhaustiveSwitchCases. When set to true, the rule reports missing cases even when the switch has a default clause, so you can keep a runtime fallback while checking that every value in the union has its own case. The option defaults to false.

    • Fixed #8347: the fix from useConsistentArrowReturn now 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: noUndeclaredCustomProperties could hang while checking stylesheets imported by JavaScript modules with many shared dependencies.

    • Fixed #7984: The fix from useSimplifiedLogicExpression now 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

  3. 2.5.13

    10 September 2026
    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 */

    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, and noUnsafePlusOperands.

    • Fixed #7495: noUselessConstructor now ignores TypeScript constructors that forward at least one argument to super, 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: useAriaPropsForRole and useFocusableInteractive no longer report non-focusable elements with role="separator". A separator with an explicit tabIndex or tabindex still requires aria-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: noUnusedPrivateClassMembers now 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 as Intl.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. noUnusedVariables now 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

  4. 2.5.12

    3 September 2026
    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} />

    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:raw children 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 as const 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. Because Math.min() and Math.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: noUnresolvedImports no 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 reports this outside class members and TypeScript functions with an explicit this parameter.

      function Person(name) {
          this.name = name;
      }
    • Fixed #11529, where noFloatingPromises missed 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 declare modifier before accessibility modifiers on class properties. private declare readonly name: string is now formatted as declare 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 delete expressions.

    • F

  5. 2.5.11

    27 August 2026
    Fixed #11496: useValidAnchor now treats Astro JSX shorthand attributes like as a valid href.

    Patch Changes

    • Fixed #11496: useValidAnchor now treats Astro JSX shorthand attributes like <a {href}> as a valid href.

    • 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: noUnusedVariables no longer reports Vue <script setup> bindings used by CSS v-bind() as unused.

    • Fixed #11389: Files passed through --stdin-file-path now use full HTML support for Astro, Svelte, and Vue when it is enabled.

    • Fixed noVueRefAsOperand to track Vue refs through declaration aliases and toRefs() properties, and to recognize useTemplateRef() results. The rule no longer reports false positives such as plain ref transfers, plain toRefs() property access, defineModel() modifiers, or the supported .effect member as operands.

      The refactor enabling these fixes also improves the performance of the rule.

    • Fixed #11436: GritQL snippets such as export { $specifiers } from $source now match named re-exports with aliases, inline type modifiers, and multiple specifiers.

    • Fixed #11390, where noFloatingPromises performed 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 noVueRefAsOperand so it no longer reports a callback parameter (e.g. from .find(), .map()) as an unwrapped ref value just because it's nested inside a ref(), computed(), or similar call.

      const result = computed(() => list.find((item) => item.label === "a"));

      Previously, item here was incorrectly treated as a ref value because the rule attributed it to the outer computed() call.

    • Fixed useGraphqlNamingConvention so it no longer reports GraphQL enum value definitions with comments & descriptions and now displays a more accurate diagnostic range.

    • Fixed #11214: noUnusedVariables no 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's set:html directive because untrusted content can introduce cross-site scripting vulnerabilities.

      For example, the following snippet triggers the rule:

      <div set:html={content} />
    • Fixed #10776: useVueHyphenatedAttributes no longer reports lowercase attribute names containing punctuation, such as pt:header:data-test-id and some_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-like style attributes, or JSX string style attributes.

      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

  6. 2.5.10

    21 August 2026
    Fixed 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:raw being 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 as R^{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: useStrictMode no longer reports Vue event handlers such as @click="count++".

    • Fixed #11429: Variables and imports used by Vue same-name bindings such as :disabled or v-bind:disabled are no longer reported as unused.

    • Fixed a memory leak in the LSP server where memory usage kept growing over long editor sessions.

    • Thanks

  7. 2.5.9

    17 August 2026
    Fixed #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 rage to include BIOME_BINARY, BIOME_LOG_FILE, and RUST_BACKTRACE as well as reworded explanations for better readability.

    • Added a new nursery rule useNamedLayer which 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 replacing w-4 h-4 with size-4.

    • Fixed #11328: lint/nursery/useExpect now recognizes Vitest Browser Mode expect.element() calls as assertions.

    • Fixed #11311: the CSS parser now accepts Tailwind container-query variant names in @variant, such as @xl and @max-xl. These previously produced a parse error and a noUnknownAtRules diagnostic.

      @variant @xl {
        div {
          background: red;
        }
      }
    • Fixed #9541: noUndeclaredVariables, noUnusedImports, and noUnusedVariables now 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 greet as 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, and object elements.

      - <marquee behavior="alternate"> This text will bounce </marquee>
      + <marquee behavior="alternate">This text will bounce</marquee>
    • Added the nursery rule useAstroClientOnlyDirectiveValue, which reports Astro client:only directives without an initializer.

      For example, <Component client:only /> triggers the rule.

    • Fixed #11229: The useGenericFontNames rule now treats math as a valid generic font family.

    • Fixed #11335: noComponentHookFactories now reports a use-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: noSvgWithoutTitle no longer reports an svg that uses the boolean shorthand aria-hidden (equivalent to aria-hidden={true} in React).

    • Fixed a bug where useJsxKeyInIterable incorrectly flagged Astro files.

    • Fixed #11315: Invalid CSS declarations in HTML style attributes 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.paths resoluti

  8. 2.5.8

    11 August 2026
    Added 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: useAwait no longer reports async functions that contain an await using declaration.

    • Fixed #11017: noUselessUndefined no longer reports return undefined when the enclosing function has a return type annotation other than undefined or void.

    • 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 style attribute values are now parsed as CSS. All Biome CSS lint rules are applied to the style attributes.

    • 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 @property whose initial-value does not match its syntax descriptor. For example, the following declaration triggers the rule because red is not a <length>:

      @property --size {
        syntax: "<length>";
        inherits: false;
        initial-value: red;
      }
    • Improved the diagnostic emitted by noRootType.

    • Fixed #11223: Improved the performance of noMisusedPromises when analyzing async class methods that call other methods through this.

    • Fixed #10806: noUselessFragments no longer causes Biome to panic when its unsafe fix removes a fragment used as a JSX attribute value.

    • Fixed #11178: noUndeclaredVariables no longer reports Vue's built-in instance properties, such as $slots and $attrs, in template expressions or $event in 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 syntax descriptor of @property rules.

    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 useReactCompiler

    • fix(inference): query local types before global

    • feat(lint/html): add `noSvel

  9. 2.5.7

    4 August 2026
    Added 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 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.

    • 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 as w-[400px], including in HTML/JSX class attributes, configured utility functions, and tagged templates.

    • Fixed #11176: noUnknownPseudoClass now recognizes Vue's :deep() pseudo-class inside .vue style 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 in subdirectory/biome.json:

      ├── biome.json
      └── subdirectory
          ├── biome.json
          └── lib.js
      biome 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-path is 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 () => void accepts an async callback and schedule therefore returns string:

      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) returns 42:

      type Mapper<T> = () => T;
      declare function map<T>(mapper: Mapper<T>): T;
      
      map(() => 42) || flag;
    • Fixed #11087: noUnnecessaryConditions no 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 noPositiveTabindex now suppress the rule in HTML files when the attributes of the element span multiple lines.

    • The HTML formatter now lays out the srcset attribute 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: noUnusedVariables no 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

  10. 2.5.6

    28 July 2026
    Fixed a performance regression in noMisusedPromises that caused type inference to run repeatedly while linting a file.

    Patch Changes

    • Fixed a performance regression in noMisusedPromises that 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: useHookAtTopLevel no longer reports hooks in named forwardRef components that receive a ref parameter.

    • 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 noUselessTernary quick fix now preserves operator spacing when simplifying or inverting boolean ternary expressions.

    • Fixed #10515: biome check --write was 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, noFloatingPromises now 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 noMisleadingReturnType when 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 doctype declarations.

    • The rdjson reporter now populates the severity field of each diagnostic (ERROR, WARNING, or INFO), 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 let and const. 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's no-restricted-properties rule. Biome now flags restricted member access and object destructuring, and biome migrate eslint preserves 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
  1. 2.5.5

    21 July 2026
    Fixed 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 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;
      switch (value) {
        case 1n:
          break;
      }
    • Fixed false positives in noBaseToString and useNullishCoalescing when 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 useSortedAttributes no longer triggers for HTML instructions.

    • Fixed noThenProperty failing to detect Object.fromEntries, Object.defineProperty, and Reflect.defineProperty calls with comments between their tokens.

    • Fixed #10980: useAriaPropsSupportedByRole no 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 link role instead of generic.

    • 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: noUnresolvedImports no longer reports false positives such as import type { NextRequest } from "next/server".

    • Fixed #10622: the HTML/Vue parser no longer panics on the argument-less v-bind shorthand (:="props").

      This syntax is valid Vue and equivalent to v-bind="props", so the parser now accepts it (along with the longhand v-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 noFloatingPromises checks a call to a function with multiple call signatures imported from another module.

    • Fixed check --write command. 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…

All 107 releases

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.