chore(deps): update code dependencies (dev) #8

Merged
renovate Bot merged 1 commits from renovate/dev-code-dependencies into dev 2026-09-15 21:56:38 +00:00

This PR contains the following updates:

Package Change Age Confidence
@biomejs/biome (source) 2.4.15 → 2.5.13 age confidence
ultracite (source) 7.8.0 → 7.11.1 age confidence
uv_build (source, changelog) >=0.11.14,<0.12.0 → >=0.12.13,<0.13.0 age confidence

Release Notes

biomejs/biome (@​biomejs/biome)

v2.5.13

Compare Source

Patch Changes

v2.5.12

Compare Source

Patch Changes
  • #​11440 b88f1ea Thanks @​Princesseuh! - 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} />
    
  • #​11440 b88f1ea Thanks @​Princesseuh! - Fixed Astro attribute names being split on : and . inside an expression, such as {x && <button x-on:keyup.enter={go} client:load.foo />}.

  • #​11440 b88f1ea Thanks @​Princesseuh! - Fixed a bare > in the children of an Astro expression being treated as markup, such as {x && <div>a > b</div>}.

  • #​11440 b88f1ea Thanks @​Princesseuh! - 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>}
    
  • #​11440 b88f1ea Thanks @​Princesseuh! - Fixed is:raw children inside an Astro expression being read as JSX, such as {x && <div is:raw>{not js} < & text</div>}.

  • #​11440 b88f1ea Thanks @​Princesseuh! - 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>)}.

  • #​11440 b88f1ea Thanks @​Princesseuh! - 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>}
    
  • #​11440 b88f1ea Thanks @​Princesseuh! - Added support for template literal attribute values inside an Astro expression, such as {x && <C data-x=`t${x}` />}.

  • #​11440 b88f1ea Thanks @​Princesseuh! - Fixed unquoted attribute values being rejected inside an Astro expression, such as {x && <a class=foo maxlength=255 href=/about>go</a>}.

  • #​11440 b88f1ea Thanks @​Princesseuh! - Fixed a template literal nested inside ${} breaking the rest of an Astro file, such as const href = `/blog${page === 0 ? '' : `/${page + 1}`}`;.

  • #​11440 b88f1ea Thanks @​Princesseuh! - Fixed a quote inside a regex character class breaking the rest of an Astro file, such as const unsafe = /[/"]/;.

  • #​11508 54f3a2e Thanks @​dyc3! - 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).

  • #​11585 c5c8315 Thanks @​Netail! - Fixed #​11475: noUnresolvedImports no longer reports Bun runtime built-in modules (bun, bun:bundle, bun:ffi, bun:jsc, bun:sqlite, bun:test).

  • #​11368 52a57b3 Thanks @​Austin1serb! - Fixed #​6830: Biome now reports a diagnostic for excessively deep syntax instead of overflowing the native stack while releasing the parsed tree.

  • #​11596 1fc42ed Thanks @​dyc3! - 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;
    }
    
  • #​11555 2516335 Thanks @​dyc3! - 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.

  • #​11518 0fee70c Thanks @​HarperZ9! - 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.

  • #​11580 1277af2 Thanks @​ematipico! - Fixed #​5091: Biome no longer moves comments next to the < of a generic, which causes invalid TypeScript syntax:

    - Generic<// a comment
    + Generic<
    +   // a comment
    
  • #​11577 42995d2 Thanks @​ematipico! - Fixed #​4592. Biome no longer crashes while parsing malformed delete expressions.

  • #​11590 67963b4 Thanks @​ematipico! - Fixed #​6427 so Grit plugins can use function = ... as a node argument.

  • #​11600 a689cb5 Thanks @​ematipico! - Fixed #​6644: noUnusedVariables now recognizes all interface declarations in a TypeScript declaration-merging group when the interface is referenced.

    The following snippet no longer triggers the rule.

    interface Things {
        foo: string;
    }
    
    interface Things {
        bar: string;
    }
    
    export type Key = keyof Things;
    
    interface Things {
        baz: string;
    }
    
  • #​11591 d4a0716 Thanks @​ematipico! - Fixed #​6615. noDuplicateProperties no longer reports declarations nested in block at-rules as duplicates of declarations in their parent block.

  • #​11492 f2a07aa Thanks @​santichausis! - Fixed #​11454: noMisplacedAssertion now recognises @fast-check/vitest's test.prop(...) (and .concurrent.prop, .skip.prop, etc.) as a test function, the same way it already recognises test.each. The JS formatter picks up the same recognition, so a curried test.prop(...)(...) call is now formatted with the regular breakable argument layout used for test.each/test.for, instead of the single-line-hugging layout used for plain it/test calls.

    For example, Biome no longer reports the assertion below as misplaced:

    import { fc, test } from "@fast-check/vitest";
    
    test.prop([fc.string()])("round-trips", (s) => {
      expect(s).toBe(s);
    });
    
  • #​11589 65742b3 Thanks @​ematipico! - Fixed #​4928: noUnusedVariables no longer reports a value declaration as unused when its merged namespace is referenced.

  • #​11559 472dbc2 Thanks @​levrik! - Fixed a false positive in noVueDuplicateKeys where a <script setup> variable initialized from props was reported as a duplicate of the prop it derives from. Biome now exempts any variable whose initializer references props, instead of only recognizing defineProps() and toRefs(props).

    For example, Biome no longer reports foo below as a duplicate key:

    <script setup>
    import { toRef } from 'vue';
    const props = defineProps(['foo']);
    const foo = toRef(props, 'foo');
    </script>
    
  • #​11594 6586ceb Thanks @​ematipico! - Fixed #​6640. Biome no longer crashes when linting malformed for...of statements.

  • #​11571 85b197d Thanks @​ematipico! - Fixed #​10838: useSortedAttributes no longer corrupts JSX attributes when nested JSX elements also require sorting.

  • #​11533 97e76c0 Thanks @​ematipico! - Fixed #​11520, where the Biome scanner would start analysing dependencies multiple times, leading to long and unresponsive sessions.

  • #​11564 18a0e1f Thanks @​Netail! - Fixed the diagnostic range of noInferrableTypes so it now highlights only the type instead of including the leading : colon, spaces and comments.

  • #​11540 124fdaa Thanks @​ematipico! - Fixed #11537: noShorthandPropertyOverrides now compares declarations only within the same block. The rule no longer reports @supports feature queries and correctly checks nested, @keyframes, and @page blocks.

  • #​11532 7ceb0ee Thanks @​dyc3! - Fixed #​11528: noFloatingPromises no longer reports statement-level await expressions that handle Promise values, including overloaded calls returning Promise aliases. Awaited values that resolve to arrays of Promises remain reported because their element Promises are not handled by await.

  • #​11474 3c6412e Thanks @​dyc3! - Fixed #​10241. Biome no longer reports unsupported text expression diagnostics for double-curly text in vanilla HTML, and the formatter preserves adjacent curly-brace text.

  • #​11593 6c7fd27 Thanks @​dyc3! - Added the nursery rule noVueDeprecatedScopedSlots. It reports deprecated $scopedSlots references in Vue templates and component objects, and offers an unsafe replacement with $slots. For example, Biome now reports this.$scopedSlots.default inside a Vue component.

  • #​11440 b88f1ea Thanks @​Princesseuh! - Fixed the formatter crashing on an Astro or Svelte expression spanning several lines in a file with CRLF line endings, such as <p>{a +\r\n b}</p>.

  • #​11581 f4e5ebb Thanks @​dyc3! - Added the nursery rule useModernMathApis. The rule reports legacy mathematical patterns that have direct modern Math equivalents.

    Math.sqrt(a * a + b * b);
    
  • #​11597 a20f44a Thanks @​Netail! - Added the nursery rule noBunModules, which forbids the use of Bun builtin modules (e.g. bun:sqlite, bun:ffi).

  • #​11545 7d54688 Thanks @​dyc3! - Fixed #​11542: Biome now reports HTML comments between Svelte tag attributes as parse errors.

  • #​11582 b6611dd Thanks @​ematipico! - Fixed #​3862. Biome now parses legacy Internet Explorer filter and -ms-filter values such as progid:DXImageTransform... and alpha(opacity=40).

  • #​11575 65da251 Thanks @​dyc3! - Improved the Tailwind parser's ability to recover from parsing failures. Whitespace now always allows the parser to recover and start parsing a new class.

  • #​11576 0f78499 Thanks @​ematipico! - Fixed #​3515 and #​10395, where Biome could corrupt Unicode characters while writing source received through standard input to standard output. Characters such as ⚠ and ✔ are now preserved.

  • #​11539 0fca643 Thanks @​ematipico! - Fixed #​11512, where style/noDescendingSpecificity missed lower-specificity selectors after a later higher-specificity selector with the same tail selector.

  • #​11544 040f867 Thanks @​dyc3! - Fixed #​11541: formatting a Svelte render tag followed by an HTML comment no longer duplicates the comment.

     <div>
       {@render children?.()}
       <!-- comment -->
    -  <!-- comment -->
     </div>
    
  • #​11565 ee69e0e Thanks @​ematipico! - Fixed #​11525. Now the configuration schema correctly provides auto-completion for linter domains.

  • #​11583 b19390c Thanks @​dyc3! - Fixed #​11352: useExplicitLengthCheck no longer reports length-like properties used as value-producing || fallbacks or optional chains, and it no longer offers fixes for value-producing && checks or unsafe negations.

  • #​11562 753e955 Thanks @​ematipico! - Fixed an issue where the Biome Language Server would start with logging level set to debug. This would cause logs to grow exponentially in long sessions.

  • #​11217 7d3ee9c Thanks @​dyc3! - Fixed handling of biome-ignore format suppression comments on TypeScript declared class properties with string literal names.

    class A {
    	declare /* biome-ignore format: exercise suppression checking */ 'a-b': 0;
    }
    
  • #​11497 f5d7896 Thanks @​dyc3! - Added the noInvalidFileInputAccept nursery rule. The rule reports invalid literal accept values on file inputs in JSX and HTML, and normalizes common mistakes.

    <input type="file" accept="image/jpg" />
    
  • #​11345 ac58958 Thanks @​jakeleventhal! - Improved type inference performance by avoiding resolution of unused members in object arguments.

  • #​11554 2d55931 Thanks @​Netail! - Added the new nursery rule useReactNamingConvention, which enforces naming conventions for React values assigned from createContext, useId, and useRef. A value from createContext must be a PascalCase component name ending with Context, a value from useId must be named id or end with Id, and a value from useRef must be named ref or end with Ref.

  • #​11491 1d6210b Thanks @​dyc3! - Added the nursery rule noUnmodifiedLoopCondition, which reports variables in loop conditions that are never modified in the loop.

    let node = getNode();
    while (node) {
        process(node);
    }
    

v2.5.11

Compare Source

Patch Changes
  • #​11499 9743d0c Thanks @​scs0209! - Fixed #​11496: useValidAnchor now treats Astro JSX shorthand attributes like <a {href}> as a valid href.

  • #​11437 88f805e Thanks @​Princesseuh! - Fixed #​9944: adjacent elements inside an Astro expression now parse as an implicit fragment instead of raising an error.

    {options.map(() =>
      <div />
      <div />
    )}
    
  • #​11437 88f805e Thanks @​Princesseuh! - Fixed Astro templates rejecting unclosed HTML void elements, such as {cond && <br>}.

  • #​11507 e2fc036 Thanks @​dyc3! - Fixed #​11157: noUnusedVariables no longer reports Vue <script setup> bindings used by CSS v-bind() as unused.

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

  • #​11526 372cd68 Thanks @​dyc3! - 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.

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

  • #​11515 382b15d Thanks @​dyc3! - 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.

  • #​11516 6f40e82 Thanks @​levrik! - 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.

  • #​11495 496268d Thanks @​Netail! - Fixed useGraphqlNamingConvention so it no longer reports GraphQL enum value definitions with comments & descriptions and now displays a more accurate diagnostic range.

  • #​11407 6ef52b0 Thanks @​1678092075! - Fixed #​11214: noUnusedVariables no longer reports type parameters declared by non-default function overload signatures that have an implementation.

  • #​11322 5c353e6 Thanks @​jp-knj! - 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} />
    
  • #​11462 18883b7 Thanks @​dyc3! - Fixed #​10776: useVueHyphenatedAttributes no longer reports lowercase attribute names containing punctuation, such as pt:header:data-test-id and some_attr.

  • #​11476 3270ca4 Thanks @​dyc3! - 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>
    
  • #​11191 3e5367f Thanks @​ematipico! - 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); }
    
  • #​11435 7754894 Thanks @​levrik! - 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>
    
  • #​11501 e6acded Thanks @​aminya! - Improved the performance of useArraySortCompare by skipping type inference for calls to unrelated methods.

  • #​11467 66b282c Thanks @​dyc3! - Fixed #​11464: Biome now parses parenthesized object literals returned from arrow functions when they contain a conditional expression and a nested arrow function.

  • #​11456 db9aa2a Thanks @​dyc3! - Fixed #​10278: Marked the fix for noThisInStatic as unsafe by default.

  • #​11502 652aedb Thanks @​levrik! - noGlobalAssign no longer reports assignments to a Vue <script setup> binding from a template expression, when the binding's name happens to match a built-in global (e.g. open, parent, top).

    For example, this no longer triggers a diagnostic:

    <script setup>
    const open = defineModel();
    </script>
    
    <template>
      <button @click="open = !open">Toggle</button>
    </template>
    

v2.5.10

Compare Source

Patch Changes
  • #​11403 8f7786f Thanks @​Princesseuh! - Fixed Astro rejecting JavaScript comments between attributes.

    <div /* block comment */ class="something"></div>
    <Component /* c */ client:load />
    
  • #​11403 8f7786f Thanks @​Princesseuh! - 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.

  • #​11438 3133ffa Thanks @​Princesseuh! - 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>
    
  • #​11403 8f7786f Thanks @​Princesseuh! - Fixed #​9165: an empty Astro expression such as <div>{}</div> no longer fails to parse. Astro renders {} as nothing.

  • #​11403 8f7786f Thanks @​Princesseuh! - Fixed Astro expressions containing a comment failing to parse.

    <div>{/* block comment */ x}</div>
    <div>{/* only a comment */}</div>
    
  • #​11403 8f7786f Thanks @​Princesseuh! - Added support for Astro's fragment shorthand.

    <>
      <p>a</p>
    </>
    
  • #​11403 8f7786f Thanks @​Princesseuh! - Fixed an Astro frontmatter block being cut short by a closing tag inside a string or comment.

    ---
    const a = "</script>";
    // </script> in a comment
    ---
    
  • #​11403 8f7786f Thanks @​Princesseuh! - 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
    ---
    
  • #​11403 8f7786f Thanks @​Princesseuh! - Fixed an Astro frontmatter block ending early on a line that merely starts with a dash.

    ---
    --count;
    ---
    
  • #​11403 8f7786f Thanks @​Princesseuh! - 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>
    
  • #​11403 8f7786f Thanks @​Princesseuh! - Fixed Astro rejecting attribute names that start with a colon, such as :href.

  • #​11403 8f7786f Thanks @​Princesseuh! - 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.

  • #​11403 8f7786f Thanks @​Princesseuh! - 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.

  • #​11403 8f7786f Thanks @​Princesseuh! - 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.

  • #​11403 8f7786f Thanks @​Princesseuh! - 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>
    
  • #​11403 8f7786f Thanks @​Princesseuh! - Added support for template literal attribute values in Astro, such as <div class=`a ${b} c`>.

  • #​11403 8f7786f Thanks @​Princesseuh! - Fixed Astro rejecting HTML5 unquoted attribute values that contain `, =, ' or ", such as <a href=a=b> and <a href=a'b>.

  • #​11393 dec5a8f Thanks @​1678092075! - Fixed #​11207: useStrictMode no longer reports Vue event handlers such as @click="count++".

  • #​11431 c065f99 Thanks @​levrik! - Fixed #​11429: Variables and imports used by Vue same-name bindings such as :disabled or v-bind:disabled are no longer reported as unused.

  • #​11409 405dedb Thanks @​ematipico! - Fixed a memory leak in the LSP server where memory usage kept growing over long editor sessions.

  • #​11422 a51eff7 Thanks @​dyc3! - Fixed #​11416: Biome no longer crashes when parsing incomplete {let} or {const} declarations in Svelte files.

  • #​11378 34b715c Thanks @​Netail! - Added extra rule sources from @eslint/css. biome migrate eslint detects rules in your eslint configurations more reliably.

  • #​11403 8f7786f Thanks @​Princesseuh! - Fixed {#, {/, {: and {@ being read as Svelte block openings in every HTML-like file. They are now Svelte-only, so in HTML, Vue and Angular files a sequence such as {#if x} is ordinary text instead of a parse error.

  • #​11443 8d45229 Thanks @​ematipico! - Fixed #​11390: noFloatingPromises no longer performs unnecessary type inference on call arguments when checking methods of non-generic class instances created with new.

  • #​11425 9c2667b Thanks @​dyc3! - Fixed #​6426: GritQL plugins now match and rewrite metavariables embedded in quoted strings.

  • #​11441 00317c3 Thanks @​dyc3! - Improved performance of useNamedCaptureGroup, noMisplacedAssertion, noSkippedTests, noExportsInTest, noDuplicateTestHooks, noIdenticalTestTitle, useTestHooksInOrder, and useTestHooksOnTop.

v2.5.9

Compare Source

Patch Changes
  • #​11321 41386f3 Thanks @​dyc3! - Fixed #​11315: The CSS parser now recovers at declaration boundaries after bogus declarations, allowing subsequent valid declarations to be parsed.

  • #​11248 57b197e Thanks @​yanthomasdev! - 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.

  • #​11377 a8798ea Thanks @​Netail! - Added a new nursery rule useNamedLayer which disallows anonymous cascade layers.

    @layer {
      a {
        color: red;
      }
    }
    
  • #​11327 6771cf5 Thanks @​dyc3! - 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>
    
  • #​10312 ba8aa18 Thanks @​dyc3! - Added the nursery rule useTailwindShorthandClasses, which suggests shorter Tailwind utility classes. For example, the rule suggests replacing w-4 h-4 with size-4.

  • #​11333 715e0cd Thanks @​kkkhs! - Fixed #​11328: lint/nursery/useExpect now recognizes Vitest Browser Mode expect.element() calls as assertions.

  • #​11343 9b98211 Thanks @​johncarmack1984! - 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;
      }
    }
    
  • #​11220 3e8c488 Thanks @​santichausis! - 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>
    
  • #​11300 36430eb Thanks @​dyc3! - 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>
    
  • #​11299 6559e6c Thanks @​jp-knj! - Added the nursery rule useAstroClientOnlyDirectiveValue, which reports Astro client:only directives without an initializer.

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

  • #​11365 7529811 Thanks @​MHJahanbakhsh! - Fixed #​11229: The useGenericFontNames rule now treats math as a valid generic font family.

  • #​11346 674f5f4 Thanks @​Jayllyz! - 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;
    }
    
  • #​11334 c87c46a Thanks @​zkasuran! - Fixed #​11317: noSvgWithoutTitle no longer reports an svg that uses the boolean shorthand aria-hidden (equivalent to aria-hidden={true} in React).

  • #​11364 13853b1 Thanks @​ematipico! - Fixed a bug where useJsxKeyInIterable incorrectly flagged Astro files.

  • #​11321 41386f3 Thanks @​dyc3! - Fixed #​11315: Invalid CSS declarations in HTML style attributes now produce parser diagnostics instead of causing a panic.

  • #​11325 67c3bf0 Thanks @​dyc3! - 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
     >
    
  • #​11367 fe5b5d4 Thanks @​ematipico! - Fixed TypeScript compilerOptions.paths resolution when mapping targets omit ./. Biome now resolves these targets relative to their configured path base.

  • #​11316 17e48d6 Thanks @​wanxiankai! - Fixed #​11289: the safe fix for noExtraBooleanCast now preserves parentheses around nested conditional expressions.

  • #​11254 d25d113 Thanks @​dyc3! - Fixed #​11242: Biome no longer crashes with an access violation when analysing files on Windows ARM64.

  • #​11221 85aac73 Thanks @​freeatnet! - Added the nursery rule noUnsafeTypeAssertion, which disallows TypeScript type assertions while allowing const assertions.

    const value = input as SomeType;
    
  • #​11314 7ffb677 Thanks @​ematipico! - Fixed #​11310: Restored the performance of noMisusedPromises and noFloatingPromises when analyzed expressions share deep imported type paths.

  • #​11356 6cd3263 Thanks @​johncarmack1984! - The Tailwind parser now understands modifiers on bare utilities (@container/sidebar, shadow/50).

  • #​11318 76059e9 Thanks @​johncarmack1984! - The Tailwind parser now understands container-query variants (@sm:, @max-lg:, @min-[400px]:) and child and descendant variants (*:, **:).

  • #​11357 faa2074 Thanks @​johncarmack1984! - The Tailwind parser now accepts the legacy leading ! important marker (!flex, hover:!p-4).

  • #​11344 f34e15c Thanks @​johncarmack1984! - The Tailwind parser now understands combinator selectors in arbitrary variants (has-[>svg]:, has-[+p]:), modifiers on variants (group-hover/menu:, @sm/main:), and arbitrary container-query sizes (@[400px]:).

  • #​11324 2f5d452 Thanks @​dyc3! - Fixed HTML formatting that inserted rendered whitespace between an element and touching text when the line wrapped.

      <div>
    -   before<meter value=".5"></meter>
    -   after
    +   before<meter value=".5"></meter
    +   >after
      </div>
    
  • #​11312 e65f07e Thanks @​xosnos! - Added a new nursery rule useControlLabel for both HTML and JSX, which reports interactive control elements (button, menuitem) without an accessible label.

    <button />
    
  • #​11364 13853b1 Thanks @​ematipico! - Fixed SVG parsing for files with an XML declaration followed by a PUBLIC doctype, such as <?xml version="1.0"?><!DOCTYPE svg PUBLIC "a" "b">.

  • #​11301 610ee28 Thanks @​dyc3! - Fixed parent tag wrapping when an HTML element starts or ends with a block-like or hidden child such as source, track, or param.

    - <video src="brave.webm"><track kind="subtitles" src="brave.en.vtt"></video>
    + <video src="brave.webm">
    +   <track kind="subtitles" src="brave.en.vtt">
    + </video>
    

v2.5.8

Compare Source

Patch Changes

v2.5.7

Compare Source

Patch Changes
  • #​10822 c171b3b Thanks @​pkallos! - 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.

  • #​11136 e63354c Thanks @​AkashNaickar! - Added a new nursery rule noExtendNative, which reports extending the prototype of a built-in object.

  • #​10094 e007143 Thanks @​THEjacob1000! - 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.

  • #​11184 135f476 Thanks @​subotac! - Fixed #​11176: noUnknownPseudoClass now recognizes Vue's :deep() pseudo-class inside .vue style blocks.

  • #​8239 a519f9d Thanks @​cormacrelf! - 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.

  • #​11138 8c2c6bd Thanks @​ematipico! - 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;
    
  • #​11138 8c2c6bd Thanks @​ematipico! - 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";
    
  • #​11118 9c16840 Thanks @​subotac! - 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 -->
    
  • #​11201 0e80610 Thanks @​Bishwas-py! - Fixed #​11182: suppression comments for noPositiveTabindex now suppress the rule in HTML files when the attributes of the element span multiple lines.

  • #​11079 607afd2 Thanks @​dyc3! - 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
    +   "
    + />
    
  • #​11156 fed72c7 Thanks @​saberoueslati! - Fixed #​11129: noUnusedVariables no longer reports Vue bindings as unused when they are assigned through automatically unwrapped template refs.

  • #​11124 d890b39 Thanks @​denbezrukov! - 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, #&#8203;000, transparent);
     }
    
  • #​11113 3d8ab73 Thanks @​denbezrukov! - 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;
     }
    
  • #​11127 da5c1a5 Thanks @​dyc3! - The HTML formatter now picks the quote character for an attribute by counting the quotes in the value rather than looking only for a double quote. &apos; and &quot; count as the characters they stand for, and only the character that ends up as the delimiter stays escaped:

    - <div title='123 &apos;&quot; 456'></div>
    + <div title="123 '&quot; 456"></div>
    

    Entities that are not quotes, such as &amp; or &[#&#8203;39](https://github.com/biomejs/biome/issues/39);, are left exactly as written.

  • #​11193 77035bb Thanks @​dyc3! - Fixed the HTML formatter collapsing the blank line between an element and the text that follows it. A blank line before text is now kept, the way one before another element already was:

      <div>foo</div>
    -
      text
    
  • #​11106 ad80f57 Thanks @​dyc3! - The HTML formatter now writes the HTML5 doctype in lowercase, matching Prettier:

    - <!DOCTYPE html>
    + <!doctype html>
    

    This only applies to a plain .html file whose doctype stands alone. A doctype that names a DTD keeps the case it was written with, since the rest of the declaration is not lowercased either:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    

    A .vue, .svelte, or .astro file keeps whatever the author wrote.

  • #​11188 60679db Thanks @​dyc3! - Fixed the HTML formatter printing a comment twice when it ended the line of the last element in a document:

    - text<!-- a --><!-- a -->
    + text<!-- a -->
    
  • #​11077 4dcd0d9 Thanks @​dyc3! - Fixed a bug where the HTML formatter collapsed the whitespace inside <textarea>, <xmp> and <plaintext>, changing what the page renders.

    - <textarea>
    -  line one
    - line two </textarea>
    + <textarea>line one line two</textarea>
    

    Biome now prints the content of these elements exactly as it appears in the source, matching the existing behavior for <pre>.

  • #​11194 abfbb11 Thanks @​dyc3! - Fixed the HTML formatter refusing to format a Svelte file containing an array pattern that skips a position:

    {#each animals as [, value]}
    	<p>{value}</p>
    {/each}
    
  • #​10094 e007143 Thanks @​THEjacob1000! - Fixed useSortedClasses to correctly detect unsorted classes in static member expression tagged templates (e.g. tw.div\...``). Previously, these were silently skipped due to surrounding whitespace trivia not being stripped from the tag name.

  • #​11078 10da30e Thanks @​dyc3! - Fixed Vue single-file components failing to parse when they contain a custom block such as <i18n> or <docs>, or a <template> written in another language. Their content is no longer read as HTML, so a block may hold whatever its own tooling expects:

    <docs>
    This block is prose, and it may mention a `<my-component>` without closing it.
    </docs>
    
    <template lang="pug">
      .test
        #foo
    </template>
    

    Previously both blocks produced a parse error and the whole file was left unformatted. Biome now prints their content unchanged while still formatting the opening tag.

  • #​11231 4afd901 Thanks @​ematipico! - Improved the performance of the following lint rules:

  • #​11134 2fa0a62 Thanks @​yanthomasdev! - Clarified the warning emitted when using the experimental json and json-pretty reporters.

  • #​11198 ed88b13 Thanks @​saberoueslati! - Fixed #​11171: variables referenced only inside a Svelte attachment ({@attach ...}) are no longer reported as unused by noUnusedVariables and noUnusedImports.

  • #​11155 6ee17ea Thanks @​dyc3! - Improved performance when printing diagnostics to the console.

  • #​11160 217f8ad Thanks @​dyc3! - Improved the performance of noFloatingPromises by skipping type inference for assignment statements, which are always considered handled.

  • #​11159 26c23d9 Thanks @​saberoueslati! - Fixed #​11144: noFloatingPromises no longer reports already-awaited optional Promise values.

  • #​11138 8c2c6bd Thanks @​ematipico! - Fixed #​11121: noUnnecessaryConditions no longer reports conditions based on an inapplicable function overload.

    For example, the condition in the following code is no longer reported because query({}) selects the overload that returns boolean:

    declare function query(options: { initial: string }): { isPending: false };
    declare function query(options: { initial?: string }): { isPending: boolean };
    
    const { isPending } = query({});
    isPending || fallback;
    
  • #​11152 c4fc6a9 Thanks @​dyc3! - Improved the performance of collecting rule timings with --profile-rules in heavily multithreaded environments.

  • #​11128 4d3ff76 Thanks @​ematipico! - Fixed #​7635: noDeprecatedImports now detects deprecated ambient declarations that are exported separately.

  • #​11117 01f7ef5 Thanks @​subotac! - Fixed #​11014: noDelete no longer reports process.env["FOO"] style property deletions.

  • #​11168 9847e68 Thanks @​saberoueslati! - Added the nursery rule noNonScalableViewport, which reports viewport metadata that disables user scaling with user-scalable=no.

    For example:

    <meta name="viewport" content="width=device-width, user-scalable=no" />
    
  • #​11154 a1d6b1f Thanks @​dyc3! - Improved the performance of noImportCycles by skipping graph traversals for imports that cannot be part of a cycle.

  • #​11175 d96d6dd Thanks @​ematipico! - Fixed CSS parsing of registered custom properties: Biome now correctly validates the syntax descriptor of @property rules.

v2.5.6

Compare Source

Patch Changes
  • #​11035 0e4b03b Thanks @​ematipico! - Fixed a performance regression in noMisusedPromises that caused type inference to run repeatedly while linting a file.

  • #​11043 22ec076 Thanks @​denbezrukov! - Fixed CSS formatting for multiline function arguments preceded by comments:

     .example {
       value: outer(
         1,
         /* comment */
         nested(
    -      first,
    -      second
    -    )
    +        first,
    +        second
    +      )
       );
     }
    
  • #​11007 c9acb25 Thanks @​BTF-Kabir-2020! - Fixed #​9195: useHookAtTopLevel no longer reports hooks in named forwardRef components that receive a ref parameter.

  • #​10152 50a9bd8 Thanks @​Zelys-DFKH! - 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.

  • #​11105 8ffe2b9 Thanks @​dadavidtseng! - Fixed #​11092: The noUselessTernary quick fix now preserves operator spacing when simplifying or inverting boolean ternary expressions.

  • #​10533 5809875 Thanks @​Mokto! - 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.

  • #​11040 0abb620 Thanks @​Mokto! - 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.

  • #​10858 6d18204 Thanks @​ruidosujeira! - 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.

  • #​11009 2c36626 Thanks @​ematipico! - 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);
    
  • #​10973 9cb044c Thanks @​ematipico! - 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;
    }
    
  • #​11071 15047a2 Thanks @​dyc3! - The HTML parser now accepts mixed-case doctype declarations.

  • #​11030 cc90e65 Thanks @​marschattha! - 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.

  • #​11009 2c36626 Thanks @​ematipico! - Fixed a performance regression in type-aware JavaScript lint rules by inferring only requested types and memoizing export resolution.

  • #​11056 903b177 Thanks @​dyc3! - Added support for Svelte declaration tags using let and const. Biome can now parse, format, and lint bindings declared in these tags.

  • #​11045 89c27c6 Thanks @​ematipico! - Improved the performance of Biome formatter up to ~7% across the board.

  • #​9806 781d68d Thanks @​dyc3! - 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.

v2.5.5

Compare Source

Patch Changes
  • #​10972 ab8c21b Thanks @​ematipico! - 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;
    }
    
  • #​10972 ab8c21b Thanks @​ematipico! - 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";
    
  • #​10977 0bf7486 Thanks @​ematipico! - Fixed #​10922: the action useSortedAttributes no longer triggers for HTML instructions.

  • #​10957 cf263c4 Thanks @​dyc3! - Fixed noThenProperty failing to detect Object.fromEntries, Object.defineProperty, and Reflect.defineProperty calls with comments between their tokens.

  • #​10983 edc0ed7 Thanks @​ayaangazali! - 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.

  • #​10889 89526e3 Thanks @​denbezrukov! - 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; } }
    
  • #​10964 794ccd0 Thanks @​denbezrukov! - Fixed CSS formatting for comments between declaration values and !important.

    -a { color: /* before */ /* after */ red !important; }
    +a { color: /* before */ red /* after */ !important; }
    
  • #​10993 b7a9694 Thanks @​denbezrukov! - 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"] {}
    
  • #​10978 8ebafe1 Thanks @​ematipico! - Fixed #​10870: noUnresolvedImports no longer reports false positives such as import type { NextRequest } from "next/server".

  • #​10901 68c10e6 Thanks @​Socialpranker! - 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.

  • #​10936 7df46f5 Thanks @​ematipico! - Improved generic tuple inference for useIncludes. The rule now recognizes specialised tuple element types returned through generic aliases.

  • #​10941 f787725 Thanks @​siketyan! - Fixed #10855: Biome now supports parsing and formatting CSS custom media queries declared with @custom-media.

  • #​10969 72d309b Thanks @​ematipico! - Fixed an issue where Biome logs became too verbose, dumping information not relevant to user's operations.

  • e62f6b6 Thanks @​ematipico! - 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.

  • #​10931 899c60d Thanks @​ematipico! - Fixed check --write command. Now the command reports code frame of the formatted code, if the formatter is enabled.

  • #​10904 ceee4f4 Thanks @​qzwxsaedc! - Fixed #​10892: noUnnecessaryConditions no longer reports a false positive when checking a member of a discriminated union that is accessed through a default type-only namespace import. The following code is no longer flagged:

    import type Types from "./types";
    
    declare function parse(): Types.Result<string>;
    const result = parse();
    if (!result.success) {
    }
    
  • #​10962 f0a67f2 Thanks @​ematipico! - Biome no longer removes embedded styles and scripts in HTML files.

  • #​11000 5039a1e Thanks @​ematipico! - Fixed a bug where closing one editor stopped a shared Biome daemon used by other editors. LSP proxy processes now exit when either the editor or daemon disconnects.

  • #​10957 cf263c4 Thanks @​dyc3! - Improved the performance of the noThenProperty lint rule by about 50%.

  • #​10992 4bf9b21 Thanks @​ematipico! - Fixed noMisusedPromises: The rule now reports Promise-returning callbacks where a synchronous callback is expected when calls use tuple spreads or tuple rest parameters, including generic and deeply nested tuples, and when constructor signatures come from interface or object types. Recursive or excessively nested tuple spreads use a conservative fallback so analysis terminates.

    For example, the following callback is now reported.

    declare function consume(...args: [number, () => void]): void;
    const prefix: [number] = [1];
    
    consume(...prefix, async () => {});
    
  • #​10915 b3b12b3 Thanks @​Functionhx! - Added the rule noNegationInEqualityCheck. The rule flags negated expressions on the left side of strict equality checks like !foo === bar — due to operator precedence this evaluates as (!foo) === bar which is almost always a mistake for foo !== bar.

    The rule provides an unsafe fix that flips the operator.

    // Invalid
    !foo === bar;
    !foo !== bar;
    
    // Valid
    foo !== bar;
    foo === bar;
    
  • #​10970 bd1038b Thanks @​ematipico! - Improved overload selection for noMisusedPromises. Biome now handles overloaded calls, overloaded constructors, rest parameters, union arguments, and generic constraints without selecting an incompatible signature. For example, noMisusedPromises now reports the async callback passed to the synchronous overload:

    declare function consume(kind: "async", callback: () => Promise<void>): void;
    declare function consume(kind: "sync", callback: () => void): void;
    consume("sync", async () => {});
    
  • #​10933 48a4abb Thanks @​ematipico! - Fixed useArrayFind to recognize bigint zero indexes.

  • #​10931 899c60d Thanks @​ematipico! - Fixed an orchestration issue that could lead to deadlocks when type-aware rules are enabled.

  • #​10969 72d309b Thanks @​ematipico! - Hardened the Biome Language Server by improving its synchronisation logic.

  • #​10972 ab8c21b Thanks @​ematipico! - Fixed false positives in noMisusedPromises and useAwaitThenable when Promise or thenable inference cannot complete. These rules now suppress diagnostics instead of treating incomplete type information as a definite result. For example, useAwaitThenable no longer reports await value when the value's thenability is unknown:

    declare const value: unknown;
    
    async function consume() {
      await value;
    }
    

v2.5.4

Compare Source

Patch Changes
  • #​10665 55ff995 Thanks @​dyc3! - Improved the performance of the HTML parser slightly in our synthetic benchmarks.

  • #​10894 f4fb10e Thanks @​ematipico! - Fixed #​6392: On-type formatting no longer moves comments before an if statement into its body.

  • #​10939 f2799db Thanks @​Netail! - Fixed #​10930: noLabelWithoutControl now correctly detects text interpolation in Astro, Svelte & Vue as valid accessible content.

  • #​10945 ae15d98 Thanks @​Netail! - Fixed #​10942: Svelte directives don't throw an accidental debug log anymore.

  • #​10842 5e1abfe Thanks @​JamBalaya56562! - Fixed #​9196: biome check --write --unsafe no longer hangs forever when applying the noCommentText code fix.

    The rule's fix now wraps the comment in a real JSX expression container ({/* comment */}) instead of re-inserting the braces as plain JSX text, so the fixed code is no longer reported again by the same rule.

  • #​10891 ecca79e Thanks @​ematipico! - Fixed #10885: prevented a module-inference regression introduced by a housekeeping change.

  • #​10886 60c8043 Thanks @​dyc3! - Fixed #​10727: Biome now breaks the arguments of curried test.each, it.each, describe.each, and test.for calls when they exceed the configured line width.

    - test.each([[1, 2]])("a description that is long enough to push the hugged opening line beyond the print width", (a, b) => {
    -   expect(a).toBe(b);
    - });
    + test.each([[1, 2]])(
    +   "a description that is long enough to push the hugged opening line beyond the print width",
    +   (a, b) => {
    +     expect(a).toBe(b);
    +   },
    + );
    
  • #​10895 01a85f0 Thanks @​ematipico! - Biome will now remove stale Unix daemon sockets from older Biome versions when starting a newer daemon.

v2.5.3

Compare Source

Patch Changes
  • #​10815 86613d5 Thanks @​WaterWhisperer! - Fixed a parser panic reported in #​10708: Biome now recovers when unsupported CSS Modules @value rules or scoped @keyframes names end at EOF.

  • #​10534 da9b403 Thanks @​Mokto! - Fixed noUnusedVariables false positives in Svelte files: Svelte store subscriptions ($store references in templates now keep the underlying store binding from being flagged), and $bindable() props that are only written to in the script block (write-only is intentional for bindable props) are no longer reported as unused.

  • #​10827 098ba41 Thanks @​Aqu1bp! - Fixed #​10698: The noUnsafeOptionalChaining rule now reports unsafe optional chains wrapped in TypeScript as, satisfies, type assertion, and instantiation expressions, such as new (value?.constructor as Constructor)().

  • #​10773 3c6513d Thanks @​otkrickey! - Fixed #​10772: useVueValidVOn no longer reports a missing handler for v-on directives using a verb modifier (.stop / .prevent) without an expression, e.g. <div @click.stop></div>. The rule also accepts the arg-less object syntax <div v-on="$listeners"></div> instead of reporting a missing event name.

  • #​10721 d83c66b Thanks @​minseong0324! - Improved type-aware lint rule inference for built-in globals and indexed function calls. Biome now resolves Error(...), new Error(...), optional Error#stack, and calls through indexed function values such as handlers[0]() more accurately.

  • #​10865 6450276 Thanks @​ematipico! - Fixed #​10845. Biome Language Server no longer goes in deadlock when the scanner is enabled.

  • #​10853 93d8e53 Thanks @​Netail! - Fixed #​10840: Astro shorthand attribute syntax is now correctly being parsed from embedded nodes.

  • #​10820 bba3092 Thanks @​JamBalaya56562! - Fixed #​10619: noProcessEnv now also reports computed (bracket) member access. Previously only dot access was checked, so process["env"] and env["NODE_ENV"] (where env is imported from node:process) were missed. Both static and computed accesses are now reported.

  • #​10835 3447b2f Thanks @​dyc3! - Fixed #​10824: useDomQuerySelector now supports an ignore option for receiver identifiers that should not be reported.

  • #​10875 b12e486 Thanks @​dyc3! - Fixed #​10795: --profile-rules now reports timings for each plugin separately as plugin/<pluginName>, matching the naming used by plugin suppressions, instead of aggregating all plugins under a single plugin/plugin entry.

  • #​10877 d6bc447 Thanks @​ematipico! - Fixed biome-zed#164: Biome no longer inserts stray whitespace when format-on-type runs after closing delimiters such as ), ], and }.

  • #​10867 a21463e Thanks @​dyc3! - Fixed #​10864: Biome no longer crashes when checking or linting HTML files with unquoted attribute values such as <textarea rows=4></textarea>.

v2.5.2

Compare Source

Patch Changes
  • #​10595 f458028 Thanks @​pkallos! - Added the option ignoreBooleanCoercion to useNullishCoalescing. When enabled, Biome ignores || and ||= used inside a Boolean() call, where coalescing on falsy values is intentional.

  • #​10798 4a32b63 Thanks @​pkallos! - Added the option ignorePrimitives to useNullishCoalescing. When enabled, Biome ignores ||, ||=, and ternary expressions whose non-nullish operands are all primitives the option opts out of. Use true to ignore all primitives, or an object selecting string, number, boolean, or bigint.

  • #​10545 f3d4c00 Thanks @​Mokto! - Added the new nursery rule noSvelteUnnecessaryStateWrap, which reports unnecessary $state() wrapping of classes from svelte/reactivity that are already reactive.

    <script>
    import { SvelteMap } from "svelte/reactivity";
    const map = $state(new SvelteMap()); // redundant
    </script>
    
  • #​10752 f62fb8b Thanks @​ematipico! - Fixed #​10739. Now the rule useValidAutocomplete correctly flags the autoComplete attribute.

  • #​10796 f1b3ab2 Thanks @​ematipico! - Fixed #​10768. Improved the performance of the Biome Language Server by cancelling certain in-flight operations when there are fast updates.

  • #​10719 aa649b5 Thanks @​minseong0324! - Fixed noMisleadingReturnType false positive on returns that use a widening type assertion: "a" as string is no longer reported as misleading. The rule now also reports a literal-pinning assertion such as false as false, matching the existing as const behavior.

    // No longer flagged (returns are `string`):
    function getValue(b: boolean): string {
      if (b) return "a" as string;
      return "b" as string;
    }
    
    // Now also reported, like `as const` (returns `false`):
    function isReady(): boolean {
      return false as false;
    }
    
  • #​10678 8f073a7 Thanks @​PranavAchar01! - Fixed #​7718: Biome now correctly parses CSS nesting selectors when & appears as a trailing sub-selector after a type selector, e.g. h1& { color: red; }.

  • #​10756 5ec965a Thanks @​denbezrukov! - Fixed CSS formatter output for selector lists with allowWrongLineComments and // comments after a selector comma. Biome now keeps the selector before the line comment inline instead of breaking it across descendant combinators.

    -.powerPathNavigator
    -  .helm
    -  button.pressedButton, // pressed
    +.powerPathNavigator .helm button.pressedButton, // pressed
     .powerPathNavigator .helm button:active:not(.disabledButton) {
     }
    
  • #​10757 6232fcd Thanks @​PranavAchar01! - Fixed #​8269: the CSS parser now accepts Tailwind @variant and @utility names that start with a digit, such as the 2xl breakpoint.

    @utility container {
      @variant 2xl {
        max-width: 1400px;
      }
    }
    
  • #​10777 575ced6 Thanks @​WaterWhisperer! - Fixed an issue reported in #​10708: the GitLab reporter now handles --verbose diagnostics filtering correctly.

  • #​10281 0efe244 Thanks @​Zelys-DFKH! - Fixed a bug where GritQL patterns rejected positional (unkeyed) arguments.

  • #​10758 e36fd8a Thanks @​henrybrewer00-dotcom! - Fixed #​10697: The formatter no longer removes the parentheses around an await or yield expression used as the target of a TypeScript instantiation expression. For example, (await makeFactory)<Value> is no longer reformatted to await makeFactory<Value>, which would change the meaning of the code.

  • #​10586 3617094 Thanks @​IxxyDev! - Fixed #​9568: noFloatingPromises no longer reports a false positive when calling an overloaded function and the selected overload does not return a promise.

    function bestEffort(cb: () => Promise<number>): Promise<number>;
    function bestEffort(cb: () => number): number;
    function bestEffort(
      cb: () => number | Promise<number>,
    ): Promise<number> | number {
      return cb() as Promise<number> | number;
    }
    
    // This resolves to the second overload, which returns `number`, so it is no
    // longer flagged as a floating promise.
    bestEffort(() => 42);
    
  • #​10766 7aff4c1 Thanks @​JamBalaya56562! - Fixed #​2862: noInteractiveElementToNoninteractiveRole no longer reports custom elements (a tag name containing a dash, e.g. <my-button role="img" />). Per the W3C HTML-ARIA specification, a custom element may be given any role or none.

  • #​10680 771daa4 Thanks @​WaterWhisperer! - Fixed #​10635: Biome now recognizes chained
    table tests such as test.concurrent.each() and it.concurrent.each() as test calls, fixing
    noMisplacedAssertion false positives and improving formatting for those test declarations.

  • #​10759 34570b5 Thanks @​henrybrewer00-dotcom! - Fixed #​10636: noStaticElementInteractions no longer reports a false positive for event handlers on Svelte special elements such as <svelte:window>, <svelte:document>, and <svelte:body>. These are not real DOM elements, so they are now ignored by the rule.

  • #​10741 bd2364e Thanks @​JamBalaya56562! - Fixed #​6686: the rage command now respects the --config-path option and the BIOME_CONFIG_PATH environment variable when loading the Biome configuration. Previously it always used the default configuration resolution and reported the configuration as Not set when no biome.json existed in the working directory.

  • #​10763 2c3e82d Thanks @​Aqu1bp! - Fixed #​10742: noSolidDestructuredProps now reports destructured props in Solid function components and JSX children.

  • #​10606 a4cc4ab Thanks @​Mokto! - Fixed false positives in noUnusedImports, noUnusedVariables, and useImportType for Svelte components that use both a <script module> and a <script> block. The two blocks compile to a single module and share a top-level scope, so a binding (import, function, or variable) declared in one block and used only in the other is no longer reported as unused.

  • #​10767 36d5aa7 Thanks @​otkrickey! - Fixed #​10754: useVueValidVBind no longer reports the Vue 3.4+ same-name shorthand as missing a value. :foo and v-bind:foo are now accepted as equivalent to :foo="foo", while v-bind, v-bind:[dynamicArg], and :[dynamicArg] without a value continue to be reported.

  • #​10775 a918af0 Thanks @​WaterWhisperer! - Fixed an issue reported in #​10708: biome rage didn't detect running Biome daemon pipes on Windows.

  • #​10730 5a2e65b Thanks @​dinocosta! - Fixed an issue where Biome was resolving the well-known Zed settings file from the wrong location on macOS and Windows.

  • #​10807 d97fffe Thanks @​ematipico! - Fixed an issue where .scss files were incorrectly analyzed when running biome check.

  • #​10672 53c6efc Thanks @​ematipico! - Fixed a bug where Biome incorrectly formatted snippets that have parsing errors.

  • #​10719 aa649b5 Thanks @​minseong0324! - Fixed useAwaitThenable false positive when awaiting a custom thenable that is not the global Promise. A value with a callable then member is now recognized as awaitable.

    interface Thenable<T> {
      then(onfulfilled: (value: T) => void): void;
    }
    declare const t: Thenable<number>;
    async function f() {
      await t;
    }
    
  • #​10734 4396496 Thanks @​BangDori! - Fixed #​10708: biome migrate now preserves trivia when migrating the deprecated recommended option to preset.

  • #​10683 ae31a00 Thanks @​Netail! - Fixed #​10657 #​10671 #​10661 #​10637 #​10718: HTML rules now correctly handle dynamic attributes.

  • #​10746 54e8239 Thanks @​ematipico! - Fixed an issue where noUndeclaredClasses didn't correctly detect styles defined inside the Astro directive is:global.

  • #​10770 dd1429c Thanks @​ematipico! - Improved the Biome Language Server DX by orchestrating certain operations, so that they won't block the editor during typing. This improvement is more visible in large documents.

  • #​10473 d9b5133 Thanks @​Mokto! - Improved noUnusedImports, noUnusedVariables, noUnusedFunctionParameters, and useImportType for Svelte, Vue, and Astro files (with html.experimentalFullSupportEnabled). Bindings used only in the template — including component tags, attribute interpolations, directives, bind: shorthand, and snippet parameters — are no longer reported as unused, while genuinely unused ones still are.

  • #​10796 f1b3ab2 Thanks @​ematipico! - Fixed an issue where the Biome Language Server didn't enable project or type-aware lint rules, even when they were explicitly enabled.

  • #​10746 54e8239 Thanks @​ematipico! - Fixed an issue where noUndeclaredClasses didn't detect styles declared inside HTML documents.

  • #​10774 bde945b Thanks @​pattrickrice! - Fixed #​10268 where a race condition resulted in internal errors such as: The file biome.json does not exist in the workspace.

v2.5.1

Compare Source

Patch Changes

v2.5.0

Compare Source

Minor Changes
  • #​9539 f0615fd Thanks @​ematipico! - Added a new reporter called concise. When --reporter=concise is passed the commands format, lint, check and ci, the diagnostics are printed in a compact manner:

    ! index.ts:2:10: lint/correctness/noUnusedImports: Several of these imports are unused.
    ! main.ts:9:7: lint/correctness/noUnusedVariables: This variable f is unused.
    × index.ts:8:5: lint/suspicious/noImplicitAnyLet: This variable implicitly has the any type.
    × main.ts:2:10: lint/suspicious/noRedeclare: Shouldn't redeclare 'z'. Consider to delete it or rename it.
    
  • #​9495 2056b23 Thanks @​aviraldua93! - Added the useKeyWithClickEvents a11y lint rule for HTML files (.html, .vue, .svelte, .astro). This is a port of the existing JSX rule. The rule enforces that elements with an onclick handler also have at least one keyboard event handler (onkeydown, onkeyup, or onkeypress) to ensure keyboard accessibility.

    Inherently keyboard-accessible elements (<a>, <button>, <input>, <select>, <textarea>, <option>) are excluded, as are elements hidden from assistive technologies (aria-hidden) or with role="presentation" / role="none".

    <!-- Invalid: no keyboard handler -->
    <div onclick="handleClick()">Click me</div>
    
    <!-- Valid: has keyboard handler -->
    <div onclick="handleClick()" onkeydown="handleKeyDown()">Click me</div>
    
    <!-- Valid: inherently keyboard-accessible -->
    <button onclick="handleClick()">Submit</button>
    
  • #​9152 9ec8500 Thanks @​ematipico! - Added new nursery lint rule noUndeclaredClasses for HTML, JSX, and SFC files (Vue, Astro, Svelte). The rule detects CSS class names used in class="..." (or className) attributes that are not defined in any <style> block or linked stylesheet reachable from the file.

    <!-- .typo is used but never defined -->
    <html>
      <head>
        <style>
          .button {
            color: blue;
          }
        </style>
      </head>
      <body>
        <div class="button typo"></div>
      </body>
    </html>
    
  • #​9152 9ec8500 Thanks @​ematipico! - Added new nursery lint rule noUnusedClasses for CSS. The rule detects CSS class selectors that are never referenced in any HTML or JSX file that imports the stylesheet. This is a project-domain rule that requires the module graph.

    /* styles.css — .ghost is never used in any importing file */
    .button {
      color: blue;
    }
    .ghost {
      color: red;
    }
    
    /* App.jsx */
    import "./styles.css";
    export default () => <div className="button" />;
    
  • #​9546 6567efa Thanks @​nhedger! - Added a biome upgrade command for standalone installations. It upgrades Homebrew installs with brew upgrade biome, updates manually installed binaries from the latest GitHub release, and tells npm users to upgrade with their package manager instead.

  • #​9716 701767a Thanks @​faizkhairi! - Added the HTML version of the useHeadingContent rule. The rule now enforces that heading elements (h1-h6) have content accessible to screen readers in HTML, Vue, Svelte, and Astro files.

    <!-- Invalid: empty heading -->
    <h1></h1>
    
    <!-- Invalid: heading hidden from screen readers -->
    <h1 aria-hidden="true">invisible content</h1>
    
    <!-- Valid: heading with text content -->
    <h1>heading</h1>
    
    <!-- Valid: heading with accessible name -->
    <h1 aria-label="Screen reader content"></h1>
    
  • #​9582 f437ef8 Thanks @​rahuld109! - Added the HTML version of the useKeyWithMouseEvents rule. The rule now enforces that onmouseover is accompanied by onfocus and onmouseout is accompanied by onblur in HTML, Vue, Svelte, and Astro files.

    <!-- Invalid: onmouseover without onfocus -->
    <div onmouseover="handleMouseOver()"></div>
    
    <!-- Valid: onmouseover paired with onfocus -->
    <div onmouseover="handleMouseOver()" onfocus="handleFocus()"></div>
    
  • #​9275 1fdbcee Thanks @​ff1451! - Added the new assist action useSortedTypeFields, which sorts the fields of GraphQL object types, interface types and input object types alphabetically, e.g. name, age, id becomes age, id, name.

  • #​10561 78075b7 Thanks @​Conaclos! - Added a new style option to useExportType,
    which enforces a style for exporting types.
    This is the same option as the one provided by useImportType.

  • #​8987 d16e32b Thanks @​DerTimonius! - Ported the useValidAnchor rule to HTML. This rule enforces that all anchors are valid and that they are navigable elements.

  • #​9533 4d251d4 Thanks @​ematipico! - The init command now prints the Biome logo.

  • #​10069 0eb9310 Thanks @​Netail! - Added the HTML lint rule noStaticElementInteractions, which enforces that static, visible elements (such as <div>) that have click handlers use the valid role attribute.

    Invalid:

    <div onclick="myFunction()"></div>
    
  • #​9134 2a43488 Thanks @​ematipico! - Added the assist action useSortedPackageJson.

    This action organizes package.json fields according to the same conventions as the popular sort-package-json tool.

  • #​9309 7daa18b Thanks @​Bertie690! - The allowDoubleNegation option has been added to noImplicitCoercions to allow ignoring double negations inside code.

    With the option enabled, the following example is considered valid and is ignored by the rule:

    const truthy = !!value;
    
  • #​9700 894f3fb Thanks @​ematipico! - The Biome Language server now supports the "go-to definition" feature.

    When the cursor of the mouse is hovering an entity (variable, CSS class, type, etc.), and the command CTRL + click is triggered, the editor jumps to where this entity is defined, if the language server can find it.

    Here's what Biome is able to resolve:

    • Variables and types used in JavaScript modules, defined in the same file or imported from another module.
    • JSX Components used in JavaScript modules, defined in the same file or imported from another module.
    • CSS classes used in JSX and HTML-ish files (Vue, Svelte and Astro), and defined in CSS files.
    • Components used in HTML-ish files and defined in other HTML-ish.
    • Variables used in HTML-ish files and defined in the same file or imported from another module (JavaScript or HTML-ish).
  • #​10070 bae0710 Thanks @​Conaclos! - Added the :STYLE: group matcher for organizeImports that matches style imports.

    For example, the following configuration...

    {
      "assist": {
        "actions": {
          "source": {
            "organizeImports": {
              "level": "on",
              "options": {
                "groups": ["**", "!:STYLE:"],
                "sortBareImports": true
              }
            }
          }
        }
      }
    }
    

    ...places style imports last:

    - import "./style.css"
      import A from "./a.js"
    + import "./style.css"
    
  • #​9170 e3107de Thanks @​mdrobny! - Added bundleDependencies option to NoUndeclaredDependencies rule.

    This rule now supports imports of packages that are defined only in bundleDependencies and bundledDependencies arrays.

  • #​9547 01f8473 Thanks @​mujpao! - Added new assist rule useSortedAttributes for HTML, porting the existing JSX rule. This rule enforces sorted HTML attributes.

    Invalid

    <input type="text" id="name" name="name" />
    
  • #​9366 2ca1117 Thanks @​dyc3! - Added the html.parser.vue configuration option. When enabled, it adds support for the parsing of Vue in .html files. Most Vue users don't need to enable this option since Vue files typically use the .vue extension, but it can be useful for projects that embed Vue syntax in regular HTML files.

  • #​9073 74b20ee Thanks @​chocky335! - Added support for applying GritQL plugin rewrites as code actions. GritQL plugins that use the rewrite operator (=>) now produce fixable diagnostics for JavaScript, CSS, and JSON files. By default, plugin rewrites are treated as unsafe fixes and require --write --unsafe to apply. Plugin authors can pass fix_kind = "safe" to register_diagnostic() to mark a fix as safe, allowing it to be applied with just --write.

    Example plugin (useConsoleInfo.grit):

    language js
    
    `console.log($msg)` as $call where {
        register_diagnostic(span = $call, message = "Use console.info instead of console.log.", severity = "warn", fix_kind = "safe"),
        $call => `console.info($msg)`
    }
    

    Running biome check --write applies safe rewrites. Unsafe rewrites (the default, or fix_kind = "unsafe") still require --write --unsafe.

  • #​9384 f4c9edc Thanks @​Conaclos! - Added the sortBareImports option to organizeImports,
    which allows bare imports to be sorted within other imports when set to false.

    {
      "assist": {
        "actions": {
          "source": {
            "organizeImports": {
              "level": "on",
              "options": { "sortBareImports": true }
            }
          }
        }
      }
    }
    
    - import "b";
      import "a";
    + import "b";
      import { A } from "a";
    + import "./file";
      import { Local } from "./file";
    - import "./file";
    
  • #​8731 e7872bf Thanks @​siketyan! - Added the watch mode (--watch) to the CLI for check/format/lint commands. By enabling this option, Biome will re-run the check automatically when any file in the workspace has changed after the first run.

  • #​10106 9b35f78 Thanks @​ematipico! - Biome can now format and lint .svg files.

  • #​9967 e9b6c17 Thanks @​dyc3! - Added HTML support for noExcessiveLinesPerFile. Biome now reports HTML files that exceed the configured line limit, including when skipBlankLines is enabled.

  • #​9491 b3eb63c Thanks @​IxxyDev! - Added the HTML lint rule noAriaUnsupportedElements. This rule enforces that elements that do not support ARIA roles, states, and properties (meta, html, script, style) do not have role or aria-* attributes.

    <!-- Invalid: meta does not support aria attributes -->
    <meta charset="UTF-8" role="meta" />
    
  • #​9306 afd57a6 Thanks @​viraxslot! - Added the noNoninteractiveTabindex lint rule for HTML. This rule enforces that tabindex is not used on non-interactive elements, as it can cause usability issues for keyboard users.

    <div tabindex="0">Invalid: non-interactive element</div>
    `
    
  • #​9276 6d041d9 Thanks @​IxxyDev! - Added the HTML lint rule noRedundantRoles. This rule enforces that explicit role attributes are not the same as the implicit/default role of an HTML element. It supports HTML, Vue, Svelte, and Astro files.

    <!-- Invalid: role="button" is redundant on <button> -->
    <button role="button"></button>
    
  • #​9813 69aadc2 Thanks @​ematipico! - Added a new linter configuration called preset. With the new option, users can enable different kinds of rules at once.

    The following presets are available:

    • "recommended": it enables all Biome-recommended rules, or recommended rules of a group;
    • "all": it enables all Biome rules, or enables all rules of a group;
    • "none": it disables all Biome rules, or disable all rules of a group.

    You can enable recommended rules:

    {
      "linter": {
        "rules": {
          "preset": "recommended"
        }
      }
    }
    

    You can enable all rules at once:

    {
      linter: {
        rules: {
          preset: "all", // enables all rules
        },
      },
    }
    

    Or enable all rules for a group:

    {
      linter: {
        rules: {
          style: {
            preset: "all", // enables all rules in the style group
          },
        },
      },
    }
    

    This new option, however, doesn't affect how nursery rules work. Nursery rules must be enabled singularly, due to their nature.

    This new option is meant to replace recommended, so make sure to run the migrate command.

  • #​10022 3422d71 Thanks @​Netail! - Added the HTML lint rule noNoninteractiveElementToInteractiveRole, which enforces that interactive ARIA roles are not assigned to non-interactive HTML elements.

    Invalid:

    <h1 role="checkbox"></h1>
    
  • #​8396 13785fc Thanks @​apple-yagi! - Biome now supports pnpm catalogs (default and named) when resolving dependencies for linting. This behavior is opt-in and requires setting javascript.resolver.experimentalPnpmCatalogs to true.

  • #​10028 1009414 Thanks @​Netail! - Added the HTML lint rule noInteractiveElementToNoninteractiveRole, which enforces that non-interactive ARIA roles are not assigned to interactive HTML elements.

    Invalid:

    <input role="img" />
    
  • #​9853 816302f Thanks @​Netail! - Added the new assist action useSortedSelectionSet, which sorts GraphQL selection sets alphabetically, e.g. name, age, id becomes age, id, name.

    Invalid:

    query {
      name
      age
      id
    }
    
  • #​10074 9c7c6eb Thanks @​georgephillips! - Added a kind field to the ImportMatcher used by the organizeImports assist action. The new field selects imports by their syntactic kind and currently supports bare (matching side-effect imports such as import "polyfill") with optional ! negation (!bare). The matcher composes with the existing type and source fields, so users can express patterns such as "only bare imports that import a CSS file" ({ "kind": "bare", "source": "**/*.css" }).

    For example, with the following configuration:

    {
      "assist": {
        "actions": {
          "source": {
            "organizeImports": {
              "level": "on",
              "options": {
                "sortBareImports": true,
                "groups": [
                  { "kind": "!bare" },
                  ":BLANK_LINE:",
                  { "kind": "bare" }
                ]
              }
            }
          }
        }
      }
    }
    

    ...the following code:

    import "./register-my-component";
    import { render } from "react-dom";
    import "./polyfill";
    import { Button } from "@/components/Button";
    

    ...is organized as:

    import { render } from "react-dom";
    import { Button } from "@/components/Button";
    
    import "./polyfill";
    import "./register-my-component";
    
  • #​9171 ce65710 Thanks @​chocky335! - Added includes option for plugin file scoping. Plugins can now be configured with glob patterns to restrict which files they run on. Use negated globs for exclusions.

    {
      "plugins": [
        "global-plugin.grit",
        {
          "path": "scoped-plugin.grit",
          "includes": ["src/**/*.ts", "!**/*.test.ts"]
        }
      ]
    }
    
  • #​9617 dcb99ef Thanks @​faizkhairi! - Ported useAriaActivedescendantWithTabindex a11y rule to HTML.

  • #​9496 1dfb829 Thanks @​aviraldua93! - Added HTML support for the noAriaHiddenOnFocusable accessibility lint rule, which enforces that aria-hidden="true" is not set on focusable elements. Focusable elements include native interactive elements (<button>, <input>, <select>, <textarea>), elements with href (<a>, <area>), elements with tabindex >= 0, and editing hosts (contenteditable). Includes an unsafe fix to remove the aria-hidden attribute.

    <!-- Invalid: aria-hidden on a focusable element -->
    <button aria-hidden="true">Submit</button>
    
    <!-- Valid: aria-hidden on a non-focusable element -->
    <div aria-hidden="true">decorative content</div>
    
  • #​9792 f516854 Thanks @​Maximiliano-Zeballos! - Added the useSemanticElements lint rule for HTML. The rule now detects the use of role attributes in HTML elements and suggests using semantic elements instead.

    For example, the following code is now flagged:

    <div role="navigation"></div>
    

    The rule suggests using <nav> instead.

  • #​9761 cbbb7d5 Thanks @​Maximiliano-Zeballos! - Ported the useValidAriaProps lint rule to HTML. This rule checks that all aria-* attributes used in HTML elements are valid ARIA attributes as defined by the WAI-ARIA specification.

  • #​9928 aa82576 Thanks @​aviraldua93! - Ported useValidAriaValues to HTML. Biome now validates static aria-* attribute values in HTML elements against WAI-ARIA types, catching invalid values such as aria-hidden="yes".

  • #​10562 6642895 Thanks @​ematipico! - Promoted 73 nursery rules to stable groups.

    Four rules were renamed as part of the promotion:

Correctness

Promoted the following rules to the correctness group:

Suspicious

Promoted the following rules to the suspicious group:

Style

Promoted the following rules to the style group:

Complexity

Promoted the following rules to the complexity group:

Performance

Promoted the following rules to the performance group:

Security

Promoted the following rules to the security group:

A11y

Promoted the following rules to the a11y group:

  • noAmbiguousAnchorText (recommended)

  • #​10121 450f8e1 Thanks @​jongwan56! - Biome now applies Git's local exclude file when VCS ignore files are enabled. Files listed in .git/info/exclude are skipped the same way as files listed in .gitignore, including in linked worktrees.

  • #​9397 d5913c9 Thanks @​mvarendorff! - Added ignore option to the noUnusedVariables rule. The option allows excluding identifiers by providing a list of ignored names. It also allows excluding kinds of identifiers from this rule entirely, which may be useful when loading classes dynamically.

    For example, unused classes as well as all unused variables, functions, etc. called "unused" may be ignored entirely with the following configuration:

    {
      "ignore": {
        "*": ["unused"],
        "class": ["*"]
      }
    }
    
  • #​10089 71a21f0 Thanks @​Netail! - Added the lint rule noLabelWithoutControl to HTML, which enforces that a label element or component has a text label and an associated input.

    <label></label>
    
  • #​10015 1828261 Thanks @​Netail! - Added the HTML lint rule useAriaPropsSupportedByRole, which enforces that ARIA properties are valid for the roles that are supported by the element.

    <a href="#" aria-checked></a>
    
  • #​10234 1a51569 Thanks @​ematipico! - Added the delimiterSpacing formatter option. This option inserts spaces inside delimiters (after the opening delimiter and before the closing delimiter) when the content fits on a single line. Empty delimiters are not affected, and no space is added before the opening delimiter. The specific delimiters affected depend on the language. It can be configured globally via formatter.delimiterSpacing or per-language via javascript.formatter.delimiterSpacing, json.formatter.delimiterSpacing, and css.formatter.delimiterSpacing. Defaults to false.

    - callFn(foo)
    + callFn( foo )
    
    - const arr = [1, 2, 3];
    + const arr = [ 1, 2, 3 ];
    
    JavaScript

    When enabled, Biome inserts spaces inside parentheses (e.g., foo( a, b )), square brackets (e.g., [ a, b ]), template literal interpolations (e.g., ${ expr }), and the logical NOT operator (e.g., ! x, but in chains only after the last one: !! x). Only applies when the content fits on a single line. Empty delimiters and the space before the opening delimiter are not affected.

    - if (condition) {}
    + if ( condition ) {}
    
    - `Hello ${name}!`
    + `Hello ${ name }!`
    
    JSX

    When enabled, Biome inserts spaces inside JSX expression braces (e.g., attr={ value }) and spread attributes (e.g., { ...props }). Only applies when the content fits on a single line. Empty delimiters are not affected.

    - <Foo bar={value} />
    + <Foo bar={ value } />
    
    TypeScript

    When enabled, Biome inserts spaces inside TypeScript angle brackets (e.g., foo< T >()), indexed access types (e.g., T[ K ]), mapped types, tuple types, type parameters, and index signatures. Only applies when the content fits on a single line. Empty delimiters are not affected.

    - type Result = Map<string, number>;
    + type Result = Map< string, number >;
    
    JSON

    When enabled, Biome inserts spaces inside square brackets when the content fits on a single line. Empty brackets are not affected.

    - [1, 2, 3]
    + [ 1, 2, 3 ]
    
    CSS

    When enabled, Biome inserts spaces inside parentheses and square brackets when the content fits on a single line. Empty delimiters are not affected.

    - rgba(0, 0, 0, 1)
    + rgba( 0, 0, 0, 1 )
    
    - [data-attr]
    + [ data-attr ]
    
  • #​10461 6bac1c3 Thanks @​TXWSLYF! - Implements #​9445. Added the allowImplicit option to useIterableCallbackReturn. When enabled, callbacks can use return; to implicitly return undefined, matching ESLint's array-callback-return rule.

  • #​9571 5a8eb75 Thanks @​dyc3! - Added configurable options to the useNumericSeparators rule. Users can now customize the minimum number of digits required before adding separators and the group length for each type of numeric literal (binary, octal, decimal, hexadecimal).

    {
      "linter": {
        "rules": {
          "style": {
            "useNumericSeparators": {
              "level": "error",
              "options": {
                "decimal": {
                  "minimumDigits": 7,
                  "groupLength": 3
                },
                "hexadecimal": {
                  "minimumDigits": 4,
                  "groupLength": 2
                }
              }
            }
          }
        }
      }
    }
    
  • #​10067 6064312 Thanks @​Netail! - Added the lint rule useFocusableInteractive to HTML, which enforces elements with an interactive role and interaction handler to be focusable.

    Invalid:

    <div role="button"></div>
    
  • #​10026 fb42ac4 Thanks @​Netail! - Added the HTML lint rule noNoninteractiveElementInteractions, which disallows use event handlers on non-interactive elements.

    Invalid:

    <div onclick="myFunction()">button</div>
    
  • #​10000 2093e3e Thanks @​Netail! - Added the new assist action useSortedEnumMembers, which sorts TypeScript & GraphQL enum members.

    Invalid:

    enum Role {
      SUPER_ADMIN
      ADMIN
      USER
      GOD
    }
    
  • #​10013 ad01d3d Thanks @​Netail! - Added the HTML lint rule useValidAutocomplete, which enforces using valid values for the autocomplete attribute on input elements.

    <input autocomplete="incorrect" />
    
Patch Changes
  • #​10498 995c1ff Thanks @​citadelgrad! - Added the nursery rule useReactFunctionComponentDefinition, which enforces a consistent function type for named React function components.

    For example, the following snippet triggers the rule by default.

    const MyComponent = (props) => {
      return <div>{props.name}</div>;
    };
    
  • #​9974 ff635a9 Thanks @​pkallos! - Added ignoreMixedLogicalExpressions to useNullishCoalescing, partially addressing #​9232. When enabled, Biome ignores || and ||= mixed with && in the same expression tree.

  • #​10503 c656679 Thanks @​Mokto! - Added the new nursery rule useSvelteRequireEachKey, a Svelte lint rule that reports {#each} blocks with item bindings that are missing a key.

  • #​10516 0f29b83 Thanks @​Dotify71! - Added useIncludes to the nursery group. This rule flags comparisons of String.prototype.indexOf() or Array.prototype.indexOf() against -1 and suggests replacing them with the clearer includes() / !includes() form.

  • #​10487 0c03ee3 Thanks @​Mokto! - Fixed a Svelte parser error that incorrectly required a binding variable after {:then} and {:catch}. Biome now correctly accepts {:then} and {:catch} without a binding, as well as the {#await expr then} and {#await expr catch} shorthand forms.

  • #​10566 a4a294c Thanks @​dyc3! - Fixed useVueHyphenatedAttributes: The rule now only reports diagnostics in Vue files and ignores SVG elements.

  • #​10565 72ccf3b Thanks @​dyc3! - Fixed useVueConsistentVBindStyle: The rule no longer reports argument-less v-bind directives because they cannot be converted to shorthand syntax.

  • #​10591 6e8557b Thanks @​xsourabhsharma! - Fixed #​10563: Biome now parses comma-separated CSS Modules composes values, such as composes: classA from "./a.css", classB from "./b.css";.

  • #​10603 174b21b Thanks @​denbezrukov! - Fixed CSS formatting for grid-template-areas declarations with comments before multiline values. Biome now keeps grid area rows aligned instead of adding an extra declaration-boundary indent.

     .grid {
       grid-template-areas:
     /* row */
    -      "header header"
    -      "footer footer";
    +    "header header"
    +    "footer footer";
     }
    
  • #​10542 c3f07f7 Thanks @​dyc3! - Fixed #​10513: Biome no longer rejects literal \u sequences in quoted HTML attribute values.

  • #​10108 24e51d6 Thanks @​IxxyDev! - Fixed #​6611: noUnnecessaryConditions now uses type information to detect more redundant conditions, including ?., ??, ||, &&, comparisons against null/undefined on non-nullish operands, and case clauses that can never match the switch value.

  • #​10568 eb1ed0e Thanks @​harsha-cpp! - Fixed #​10564: useAriaPropsForRole no longer reports false positives for Vue v-bind shorthand bindings (:aria-checked, :aria-level, etc.).

  • #​10570 2ceb4fe Thanks @​Conaclos! - Improved noTsIgnore.
    The rule now reports more precisely the range of the @ts-ignore comment.

  • #​10520 b55d10f Thanks @​dyc3! - Fixed #​10519: Vue v-on event handlers with multiple inline statements are now parsed consistently with Vue.

  • #​10204 ebbf0bd Thanks @​ematipico! - Improved the performance of the Biome linter. The improvements are more visible in bigger projects that have more than ~1k files. Early tests showed that in a code base with ~2k files, Biome took less than 26% of time to finish the command.

  • #​10546 e39bb2c Thanks @​tim-we! - Fixed #10536: noUnknownFunction no longer flagged CSS contrast-color() as unknown. contrast-color() is Baseline 2026.

  • #​8012 2be0264 Thanks @​denbezrukov! - Improved the performance of the formatter in some cases. The formatter is now up to ~20% faster at formatting files.

  • #​10467 9a5855e Thanks @​Netail! - Added a new nursery rule noRestrictedDependencies, which flags imports and package.json dependency entries that have better alternatives in e18e's module replacement data.

    For example, the package globby is reported because there's a better alternative:

    import glob from "globby";
    
    {
      "dependencies": {
        "globby": "x.x.x"
      }
    }
    
  • #​10470 84b43c5 Thanks @​ShaharAviram1! - Fixed #​10447: now the rule noProcessEnv detects the use of env when it's imported from process and node:process.

  • #​10556 7ff6b16 Thanks @​ematipico! - Fixed #​10492: Biome no longer crashes with a stack overflow on certain code when a type-aware rule such as noFloatingPromises, noMisusedPromises, or noUnnecessaryConditions is enabled. For example, the following code used to crash Biome:

    function f(visitor) {
      let ctrl = visitor();
      for (const x of [0]) ctrl = ctrl();
    }
    
  • #​10532 1da3c75 Thanks @​denbezrukov! - CSS declarations with comments before : or after !important now preserve spaces before : and ;.

     .selector {
    -  padding/* name */: 1px;
    -  color: red !important /* note */;
    +  padding/* name */ : 1px;
    +  color: red !important /* note */ ;
     }
    
  • #​10491 a1b5834 Thanks @​Mokto! - Fixed the Svelte parser rejecting {#each} blocks where the binding uses object destructuring with property renaming, e.g. {#each items as { id, component: Filter }}. Biome now correctly parses and formats these rename bindings.

  • #​10490 99bc7df Thanks @​Mokto! - Fixed the CSS parser rejecting comma-separated selector lists inside :global() and :local() pseudo-class functions. Biome now correctly parses :global(.foo, .bar).

  • #​10543 c394fae Thanks @​mangod12! - Fixed #​10477: The RDJSON reporter now emits code replacement text for fix suggestions instead of the human-readable fix description.

  • #​10530 e8e1e6a Thanks @​Conaclos! - Fixed #​10493: useImportType now correctly separates types from a default named import when all imports are types and the style option is set to separatedType.

  • #​10555 263c7cc Thanks @​Mokto! - Improved Svelte lint rule accuracy for quoted attribute values containing {expression} interpolations.

    • noRedundantAlt no longer emits false positives when the alt text contains an interpolation, e.g. alt="image of {person}".
    • useButtonType no longer emits false positives for dynamic button types written as type="{dynamicType}".
    • noScriptUrl no longer emits false positives for dynamic hrefs such as href="{url}".
  • #​10489 96ef9a4 Thanks @​Mokto! - Fixed Svelte {#each} parser incorrectly rejecting TypeScript as const type assertions in the iterable expression. Biome now correctly parses {#each arr as const as item}.

  • #​10539 935c59a Thanks @​dyc3! - Improved how diagnostics print long lines of code, for example minified files where the entire source code is printed in one line.

v2.4.16

Compare Source

Patch Changes
  • #​10329 ef764d5 Thanks @​Conaclos! - Fixed an issue where diagnostics showed an incorrect location in Astro files.

  • #​10363 50aa415 Thanks @​dyc3! - Fixed HTML formatting for a case where comments could cause the formatter to split up a closing tag, which would cause the resulting HTML to be syntactically invalid.

    Input:

    <span
      ><!-- 1
    --><span>a</span
      ><!-- 2
    --><span>b</span
      ><!-- 3
    --></span>
    

    Output:

      <span
    	  ><!-- 1
    - --> <span>a</span<!-- 2
    - --> ><span>b</span><!-- 3
    + --><span>a</span><!-- 2
    + --><span>b</span><!-- 3
      --></span
      >
    
  • #​10465 0c718da Thanks @​dfedoryshchev! - Fixed diagnostics emitted by the noUntrustedLicenses rule.

  • #​10358 05c2617 Thanks @​dyc3! - Fixed #​10356: biome rage --linter now displays rules enabled through linter domains in the enabled rules list.

  • #​10300 950247c Thanks @​dyc3! - Fixed #​10265: Svelte function bindings such as bind:value={get, set} are now parsed more precisely, so noCommaOperator won't emit false positives for that syntax anymore.

  • #​9786 e71f584 Thanks @​MeGaNeKoS! - Fixed #​8480: useDestructuring now provides variableDeclarator and assignmentExpression options to control which contexts enforce destructuring, matching ESLint's prefer-destructuring configuration. Both default to {array: true, object: true}. The diagnostic for object destructuring in assignment expressions now instructs users to wrap the assignment in parentheses.

  • #​10425 1948b72 Thanks @​sjh9714! - Fixed #​10244: The useOptionalChain rule now detects negated guard inequality chains like !foo || foo.bar !== "x".

  • #​10442 001f94f Thanks @​ematipico! - Fixed #​10411: noMisusedPromises no longer causes a stack overflow when a nested function returns an object with shorthand properties that shadow destructured variables from an outer scope.

  • #​10318 9b1577f Thanks @​dyc3! - Added support for formatter.trailingCommas in overrides. This option was previously available in the top-level formatter configuration but missing from formatter overrides.

  • #​10319 2e37709 Thanks @​dyc3! - Fixed Vue and Svelte formatting for standalone interpolations in inline elements. Biome now preserves existing newlines in cases like:

    - <span> {{ value }} </span>
    + <span>
    +   {{ value }}
    + </span>
    
  • #​10365 0a58eb0 Thanks @​Netail! - Fixed #​10361: noUnusedFunctionParameters now mentions the parameter name in the diagnostic.

  • #​10439 df6b867 Thanks @​denbezrukov! - Fixed CSS and SCSS formatting for comments around declaration colons so comments between property names, colons, and values stay at the same boundary as Prettier.

     .selector {
    -  color: /* red, */
    -    blue;
    +  color: /* red, */ blue;
     }
    
  • #​10344 b30208c Thanks @​siketyan! - Fixed #10123: Corrected the noReactNativeDeepImports source rule to point to the proper upstream rule, so users can migrate from the original rule correctly.

  • #​10328 b59133f Thanks @​dyc3! - Fixed #​10309: Biome no longer adds newlines to Astro frontmatter when linter or assist --write mode is enabled.

haydenbleasel/ultracite (ultracite)

v7.11.1

Compare Source

Patch Changes
  • 24b2797: Update oxfmt to 0.67.0 and re-target the markdown ::: fence patch to the new dist chunk. The release changes no options; it fixes CSS/SCSS/Less comment preservation and a few JSDoc-cast edge cases in member chains.
  • 24b2797: Update oxlint to 1.82.0. The release adds and removes no rules, so the presets are unchanged apart from one new option: no-unmodified-loop-condition now runs with checkConditionalExpressions: true in the oxlint and ESLint core presets, so each branch of a ternary in a loop condition must be modified inside the loop rather than only the expression as a whole.
  • 24b2797: Update the ESLint family: @angular-eslint/eslint-plugin 22.5, @typescript-eslint/* 8.70, eslint-plugin-solid 0.18, eslint-plugin-vue 10.11, eslint-plugin-jsdoc 64.3.8, eslint-plugin-cypress 7.0.2, @darraghor/eslint-plugin-nestjs-typed 7.5.2 and prettier-plugin-astro 1.0. The dynamic presets pick up the seven new rules automatically: @typescript-eslint/no-generated-empty-object-type, @angular-eslint/reactive-context-must-read-signal, vue/no-shadow-native-events, and Solid's no-boolean-enumerated-attribute, no-store-mutation-outside-setter, no-unused-signal and no-write-in-pure-computation. Note that prettier-plugin-astro 1.0 is a rewrite on the Astro 7 Rust compiler (Node 22.12+); expect whitespace diffs on first run and mirror any custom compressHTML via its new astroCompressHTML option.
  • 24b2797: Refresh the stylelint lock to 17.15.0 and enable its new selector-no-unmatchable rule, which flags selectors that can never match (for example label:checked, ::before:first-child or :is(::before)).
  • a71dda4: Stop sorting object keys across the whole TanStack presets, not just route files. TanStack Query mutation options are order-sensitive too: TypeScript infers the onMutate context from context-sensitive callbacks in source order, so moving onError/onSettled above onMutate turns the context into {} and ultracite fix broke type-correct code (TS2339: Property '...' does not exist on type '{}'). Mutation and query options live anywhere (hooks, components, colocated files), so the route-file exemption could not cover them. ultracite/oxlint/tanstack now sets sort-keys to off and ultracite/biome/tanstack now sets useSortedKeys to off for all files.
  • a9db61c: Disable github/filenames-match-regex for file-based route directories (**/routes/**) in the oxlint js-plugins preset, matching the existing unicorn/filename-case exemption in the TanStack preset. TanStack Router filenames such as __root.tsx, $.tsx, and posts.$postId.tsx no longer fail the GitHub filename rule. Resolves #​799.

v7.11.0

Compare Source

Minor Changes
  • d5d241f: Add ultracite upgrade, and make version drift between Ultracite and its linter visible instead of a crash. Bumping ultracite without bumping the linter fails on the next check/fix with Biome's Found an unknown key error (and the equivalent for ESLint and Oxlint), because each release enables rules from a specific linter version.

    • ultracite upgrade installs the latest ultracite, prints a release-notes link for the versions you crossed, then hands off to the freshly installed CLI to reinstall your toolchain at the versions that release was verified with: Biome; ESLint, Prettier, Stylelint and the plugins the preset imports; or Oxlint and Oxfmt. Optional extras already in your package.json (framework plugins, Oxlint JS plugins, oxlint-tsgolint) are bumped as well. Config files are never rewritten, and the run ends with the same diagnostics as doctor.
    • ultracite doctor now checks the installed Biome, ESLint, Prettier, Stylelint, Oxlint and Oxfmt versions against the range this release supports. Too old fails the check and points at ultracite upgrade; newer than the verified range only warns.
    • The supported ranges are declared as optional peer dependencies so package managers warn when they drift: @biomejs/biome ^2.5.0, eslint ^10.0.0, prettier ^3.0.0, stylelint ^17.0.0, oxlint ^1.79.0, oxfmt >=0.40.0. ultracite init now installs Prettier and Stylelint from those ranges instead of latest.

    Requires Biome >= 2.5.0, ESLint >= 10.0.0, Prettier >= 3.0.0, Stylelint >= 17.0.0, Oxlint >= 1.79.0 and Oxfmt >= 0.40.0.

Patch Changes
  • 27d06f2: Update dependencies (@clack/prompts, semver, zod, ESLint plugins).
  • d322691: Default ultracite init to Oxlint + Oxfmt when --linter is omitted in quiet or non-interactive mode
  • c677cf5: Recommend Oxlint + Oxfmt in the ultracite init linter prompt and list it first
  • c5be848: Disable no-use-before-define in TanStack Router route files for the oxlint tanstack preset. File routes are mutually recursive (Route references the component, and the component calls Route.useParams()), so no declaration order could satisfy the rule.

v7.10.8

Compare Source

Patch Changes
  • 2a43fdd: Turn off unicorn/prefer-reflect-apply in the ultracite/oxlint/anti-slop preset. When extended after ultracite/oxlint/core, the core rule recommended rewriting Function#apply() to Reflect.apply(), which anti-slop's no-reflect-apply then rejected, leaving no way to satisfy both. Direct-call guidance for .apply() still comes from eslint/prefer-spread and eslint/no-useless-call.

  • 03196df: Update @biomejs/biome to 2.5.12. Releases 2.5.10 through 2.5.12 only add nursery rules, which the Biome presets exclude, so the presets are unchanged. The releases also carry linter and formatter fixes, including fewer noUnusedVariables false positives on merged interfaces, namespaces, and overload type parameters, an unsafe-by-default fix for noThisInStatic, and a large batch of Astro expression parsing fixes.

  • 031b867: Update oxfmt to 0.66.0. The 0.65 and 0.66 releases are formatter fixes only, mainly around comment placement between a statement head and its body, suppressed statements (decorators, typecast parens, semicolons), custom side-effect groups in sortImports, CommonMark list interruption in JSDoc, and trailing whitespace in YAML block scalars. The ::: container-directive fence patch is re-targeted to the new markdown bundle; the patched code itself is unchanged.

  • 54affee: Update oxlint to 1.81.0. The 1.80 and 1.81 releases add no rules and remove none, so the presets are unchanged and the peer range stays at ^1.79.0. Notable fixes carried in: no-use-before-define now runs on JS and JSX files, object-shorthand preserves __proto__ semantics, unicorn/prefer-math-min-max no longer applies an unsafe autofix, and JS plugin diagnostics with invalid or reversed locations are clamped instead of crashing.

  • 0b058d1: Fix ultracite fix --codex failing on recent Codex CLI releases. The Codex adapter invoked codex exec --full-auto, a flag Codex has since removed, so every attempt failed at argument parsing. It now runs codex exec --sandbox workspace-write, the equivalent non-interactive, workspace-scoped mode, which is also accepted by older Codex versions. Resolves #​794.

  • e2346bb: Update the ESLint family to latest: eslint 10.9.1, typescript-eslint 8.69.0, eslint-plugin-unicorn 74, eslint-plugin-solid 0.17, eslint-plugin-jsdoc 64.3.5, eslint-plugin-react-doctor and oxlint-plugin-react-doctor 0.9.13, globals 17.12, and the angular, nestjs-typed, next, tanstack-query, cypress, html, jest and storybook plugins. The dynamic presets pick up the new rules automatically: the solid preset gains the eleven rules added in eslint-plugin-solid 0.16 and 0.17 (removed-api, no-single-arg-create-effect, no-accessor-as-prop, valid-use-server, require-async-server-function, no-invalid-server-capture, no-browser-globals-in-server-function, no-module-scope-reactive-primitive, no-restated-default-options, prefer-onSettled-for-side-effects, prefer-structured-class), which only report Solid 2.0 issues when settings.solid.version is set to 2 and stay silent on Solid 1.x code; the nestjs preset gains forward-ref-injection-should-use-wrapper-type, swagger-file-upload-should-be-documented and uploaded-file-should-be-validated. The curated jsdoc and react-doctor lists are unchanged. No enabled rule was removed or deprecated, and the ESLint/oxlint parity check still passes.

  • 7b0456e: ultracite fix now runs lint fixes before the formatter: oxlint before oxfmt, and ESLint then Stylelint before Prettier. A fixer can insert unformatted code, such as the braces curly adds, the imports consistent-type-specifier-style splits, or the font names Stylelint requotes, and running the formatter first left that code unformatted until the next run. Fixer-inserted code is now formatted in the same run. The --claude and --codex agent passes follow the same order.

    unicorn/no-nested-ternary is now off in the oxlint and ESLint presets: its fixer adds parentheses that oxfmt and Prettier remove, so the two tools rewrote the file on every run. The core no-nested-ternary rule still reports nested ternaries.

  • 8ddc078: Enable three rules added in Stylelint 17 in the Stylelint preset: selector-no-deprecated and selector-no-invalid report selectors that CSS has dropped or that cannot parse, and relative-selector-nesting-notation is set to explicit, so nested relative selectors are written & > b rather than > b. The property-layout-mappings, unit-layout-mappings and value-keyword-layout-mappings rules are deliberately left off, since they reject every physical property, unit and keyword and can only autofix with a per-project languageOptions.directionality setting. The repo's own Stylelint lock is refreshed from 16.26.1 to 17.14.1, which the config packages already required; ultracite init already installs stylelint@latest so users are unaffected by the lock change.

  • 4609d79: Update the vendored anti-slop Oxlint plugin to upstream v0.1.2 (commit e8c4880). The rule set is unchanged; this picks up a round of correctness fixes: no-known-value-widening now also reports known values passed into local unknown-typed type predicates, no-object-parameters, no-unknown-parameters, no-unknown-returns and no-unknown-type-aliases resolve scoped and transparent generic aliases (including block-scoped aliases and forward references), no-unknown-returns covers PromiseLike<unknown>, no-unsafe-dictionary-type allows generic constraints such as T extends Record<string, unknown>, no-runtime-typeof always allows existence probes against "undefined", no-shape-in-symbol-names allows static member reads such as Zod's schema.shape, and require-safety-comment-for-type-assertion rejects empty justifications and gains a markers option (default ["SAFETY"]). Upstream also added a separate opt-in anti-slop-effect plugin for Effect projects, which is not vendored.

v7.10.7

Compare Source

Patch Changes
  • 15f7ae0: Add support for the Aube package manager: ultracite init --pm aube is now accepted and projects with an aube-lock.yaml lockfile are detected automatically

  • 1afc8fe: Re-declare selected Oxlint JS plugins on the root config so dependency analyzers see them. ultracite init --linter oxlint --js-plugins ... now generates const jsPlugins = selectJsPlugins([...]) and adds jsPlugins: jsPlugins.jsPlugins to the root config (also when the full ultracite/oxlint/js-plugins preset is extended). Knip only resolves jsPlugins from the root Oxlint config and never walks extends, so eslint-plugin-github, eslint-plugin-sonarjs, and oxlint-plugin-react-doctor were reported as unused devDependencies. Oxlint dedupes the plugin between the root and the extended preset, so linting is unchanged.

    Also fix ultracite update dropping the js-plugins preset from extends when the config used the documented import jsPlugins, { jsPluginSettings } from "ultracite/oxlint/js-plugins" form: the import parser only matched bare default imports. The regenerated full-preset config keeps settings: jsPluginSettings on the root as well.

  • 20b06bf: Ignore .alchemy across all linters and formatters. Alchemy (alchemy.run) writes local state and generated bindings to a .alchemy directory. It is now part of the shared ignore patterns synced into Biome's files.includes and imported by oxlint, oxfmt, and ESLint, and the Stylelint preset ignores it via ignoreFiles. Prettier needs no change: it already respects .gitignore/.prettierignore.

  • 6e9286c: Run lefthook install during ultracite init through the same spawn adapter as every other tool invocation instead of execSync, so it no longer goes through a shell and gets the same Windows command resolution as husky, the linters, and editor extension installs.

  • 8b24f34: Add support for the Nub package manager: ultracite init --pm nub is now accepted and projects with a nub.lock lockfile are detected automatically (requires nypm ^0.6.9)

  • 240cb6b: Install into the workspace root correctly for Nub and Aube monorepos: nypm emits no root selector for them, so nub add ran without -w and was refused. Ultracite now hands nypm pnpm's flag set for these pnpm-compatible CLIs, producing nub add --workspace-root --save-dev ultracite

  • 44ecbba: Add Vitest type-test files (**/*.{test-d,spec-d}.{ts,tsx,js,jsx}) to the test-file globs so the shared test relaxations and the Vitest rule overrides apply to them, and enable the Vitest plugin's typecheck setting in the ESLint preset so expectTypeOf/assertType count as assertions.

  • 7ba6bb8: Package the reusable Ultracite agent skill with the npm distribution.

v7.10.6

Compare Source

Patch Changes
  • 972b946: Update the oxlint presets for oxlint 1.79: replace the removed react/react-compiler rule with the 22 new React Compiler rules in the react preset, add jsdoc/no-blank-blocks and one-var to the core preset (mirrored in the ESLint presets), and require oxlint ^1.79.0
  • 2d5bbdb: Declare the jsPluginSettings named export in the ultracite/oxlint/js-plugins type declarations, so the documented (and ultracite init-generated) import jsPlugins, { jsPluginSettings } from "ultracite/oxlint/js-plugins" type-checks (#​773)
  • 56aef65: Refresh the toolchain versions that ultracite init installs into projects: @biomejs/biome 2.5.9, the ESLint plugin family (including eslint-plugin-cypress 7, eslint-plugin-jsdoc 64, eslint-plugin-solid 0.15, and eslint-plugin-unicorn 73 — the dynamic presets adopt their new rules automatically), and prettier-plugin-svelte 4.1.1 / prettier-plugin-tailwindcss 0.8.1

v7.10.5

Compare Source

Patch Changes
  • 8df6ad0: Offer the vendored anti-slop Oxlint preset during ultracite init — it now appears in the JS-plugins prompt when you pick Oxlint, and non-interactive setup accepts it via --js-plugins anti-slop. Selecting it adds ultracite/oxlint/anti-slop to the generated config's extends; since the preset is vendored inside Ultracite, nothing extra is installed.
  • cd229e9: Bump the oxlint-plugin-react-doctor pin from ^0.7.1 to ^0.9.12, so ultracite init installs the current plugin. All react-doctor rules enabled by the js-plugins presets still exist in 0.9.12, and the ported rules run in curated mode via the settings shipped alongside this release (#​771).
  • e1ac886: Pin React Doctor's ported rules to their framework-aware "curated" mode (#​771). react-doctor 0.9.x rewrote its ported oxc/react-refresh rules — notably only-export-components — with a stripped-down default mode: no framework detection, no route-file skipping, and allowConstantExport off, so Next.js route-segment exports like export const dynamic = "force-static" or metadata were flagged as non-component exports in every route file. The ESLint react preset now sets settings["react-doctor"].portedRuleMode: "curated", and generated oxlint configs apply a new jsPluginSettings export from ultracite/oxlint/js-plugins on the root config (oxlint does not merge settings from extended configs, so the setting cannot ride along inside the preset). If you extend the js-plugins preset manually, add settings: jsPluginSettings to your root oxlint config.
  • c27fe36: Generate oxlint configs that enable a subset of the JS plugins via a new selectJsPlugins export from ultracite/oxlint/js-plugins, instead of inlining the filtering logic into the generated file. The inlined block contained a typeof check that user-side lint presets flagged (anti-slop/no-runtime-typeof, #​770); the generated config is now a one-line extend, is emitted already formatted (including the previously missing blank line after imports), and re-running ultracite init migrates existing configs with the old inlined block automatically.
  • 0616523: Update the vendored anti-slop Oxlint plugin to upstream commit 446268e, picking up fixes to no-object-parameters and no-unknown-returns (respect lexical type binders in alias resolution) and a new allowInTypeGuards option on no-runtime-typeof. The ultracite/oxlint/anti-slop preset enables allowInTypeGuards, so typeof checks inside type predicate functions ((x): x is T) no longer need disable comments — predicates are the named-boundary pattern the rule pushes toward (dmmulroy/anti-slop#10).

v7.10.4

Compare Source

Patch Changes
  • 417a85a: Add an opt-in ultracite/oxlint/anti-slop preset that ships a vendored, self-contained build of the anti-slop Oxlint plugin — fifteen rules that reject low-evidence TypeScript and JavaScript patterns (unjustified type assertions, unknown leaking through signatures, Reflect-based access, module mocking, and more). Extend it alongside ultracite/oxlint/core; nothing extra to install. The preset also turns off two core rules that conflict with anti-slop's widening checks (typescript/consistent-indexed-object-style and unicorn/no-immediate-mutation) when extended after core.
  • 4d3fab8: Move suspicious/useArraySortCompare from the Biome core config to the opt-in type-aware config. The rule is in Biome's types domain — it type-infers the receiver of every method call before checking the method name, which made ultracite check up to ~260x slower on projects with expensive library types (zod, better-auth, Prisma). It now only runs when type-aware linting is explicitly enabled, alongside the other type/project-domain rules. Fixes #​768.

v7.10.3

Compare Source

Patch Changes
  • a1fa9c4: Replace the hand-rolled package exports map matching in the config-resolution doctor check with the resolve.exports library, which implements Node's full PACKAGE_TARGET_RESOLVE algorithm (wildcard patterns, key-order precedence, conditional exports, and array fallbacks). The manual node_modules walk is kept intentionally — it exists to avoid Bun's auto-install cache resolving specifiers the project's own node_modules can't.
  • 414ea80: Replace the hand-rolled monorepo workspace scan in framework detection with the find-workspaces library. Workspace declarations from package.json (array and yarn-classic object form) and pnpm-workspace.yaml — including negated globs — are now resolved by the library instead of manual pattern collection and globbing, and lerna/bolt monorepos are picked up as well.
  • a9a1989: Replace the hand-rolled upward directory walks in findNearestFile and detectLinter with the empathic library's find.any, which checks candidate names in order within each directory before moving to the parent — the same per-directory precedence the previous implementation enforced manually.
  • 27b2707: Use magicast to update ESM lint-staged config files during ultracite init. The config is now edited as an AST instead of being imported and re-serialized, so comments and function-valued entries elsewhere in the config survive the update, and the user's config code is no longer executed. If the Ultracite glob pattern is already owned by a non-array value, or the config isn't a mergeable object literal (e.g. defineConfig(...)), init warns and leaves the file untouched instead of rewriting it. CommonJS configs keep the previous behavior.
  • f2529b8: Rewrite the agent-fix progress renderer on top of log-update, cli-truncate, and string-width. log-update now owns the in-place block rewriting that was previously done with manual cursor-up/clear-line escape sequences, and line truncation is measured by display width instead of code units — so lint messages containing emoji or CJK text can no longer overflow the terminal row and corrupt the animated block.
  • 277b9d6: Replace the hand-rolled child-process handling in the agent fix runner with execa. The timeout → SIGTERM → grace period → SIGKILL escalation, stderr capture, and spawn-failure handling now use execa's timeout and forceKillAfterDelay options, which are battle-tested across platforms (including Windows kill semantics the manual implementation didn't cover). Behavior is unchanged: agent runs still time out after 5 minutes, escalate to SIGKILL after a 10-second grace period, and report a capped stderr tail.
  • 1614a80: Drop the direct cross-spawn dependency: all synchronous process spawning (linter runs, tool version checks, editor extension installs, skill installs) now goes through a small adapter over execa's sync API, which owns the Windows spawn semantics cross-spawn provided. The adapter preserves the spawnSync result shape (status/signal/error/stdout), always disables shell interpretation, and always decodes output as UTF-8. execa was already a dependency for the agent fix runner, so this consolidates on one process-spawning library.
  • ac114b4: Replace the glob dependency with fast-glob for the tsconfig.json scan during init. fast-glob was already in the dependency tree via find-workspaces, so this drops glob's transitive dependencies (minipass, path-scurry, etc.) from the install without changing behavior.

v7.10.2

Compare Source

Patch Changes
  • 1c48c68: Enable Tailwind CSS class sorting (sortTailwindcss) in the Oxfmt preset. Classes in class/className attributes and in clsx, cva, tw, twMerge, cn, twJoin, and tv calls are now sorted using the same algorithm as prettier-plugin-tailwindcss, matching the behavior of the Prettier preset (which always loads the Tailwind plugin) and the Biome preset's useSortedClasses rule. Projects without Tailwind installed are unaffected beyond class strings being sorted against the default theme, and oxfmt versions older than 0.35.0 ignore the option.
  • dc78be4: Stop sorting TanStack route option keys in route files. TanStack Router's route option types are order-sensitive (head/component infer loaderData from properties declared before them), so the Biome useSortedKeys source action rewrote createFileRoute literals into an order that breaks type inference (loaderData becomes never). The Biome TanStack preset now disables useSortedKeys for route files, and the oxlint TanStack preset disables sort-keys there so route files aren't caught between it and react-doctor/tanstack-start-route-property-order.

v7.10.1

Compare Source

Patch Changes
  • d018b7f: Fix several agent fix mode (fix --claude/--codex) issues: runs no longer abort with ENOBUFS when linter JSON output exceeds 1MB, user-supplied format/reporter flags can no longer override the JSON reporter and break parsing, a stuck agent process is force-killed 10 seconds after the timeout instead of hanging forever, and the progress renderer no longer garbles TTY output when file paths and rule names exceed the terminal width.
  • d018b7f: Fix Biome config migration leaving the legacy bare "extends": ["ultracite"] form in place, which breaks Biome's module resolution since the package has no root export. It's now mapped to ultracite/biome/core.
  • d018b7f: Fix ultracite doctor reporting spurious failures: config checks now walk up parent directories (matching check/fix and the linters themselves) so monorepo packages inheriting a root config pass, .oxlintrc.json is accepted as a valid oxlint config (with a migration suggestion), and Prettier/Stylelint configs declared via package.json keys are recognized.
  • d018b7f: Fix ultracite init corrupting existing Prettier/Stylelint/ESLint configs by writing an ESM module into JSON/YAML/TOML/CJS config files (e.g. .prettierrc, eslint.config.cjs). Updates now write the default .mjs config instead and remove the incompatible file so it can't shadow the new one.
  • d018b7f: Fix ultracite check/fix misrouting space-separated flag values (e.g. --max-warnings 10) into the file list, which scrambled the underlying linter invocation and made formatters fail on bogus targets. Positional files listed before a -- separator are also kept as lint targets instead of being reclassified as passthrough, which could silently widen formatter runs to the whole project.
  • d018b7f: Fix Lefthook and pre-commit YAML updates silently doing nothing on common config shapes: the Lefthook job is now inserted correctly when jobs: isn't the first key under pre-commit: (and no longer matches a jobs: key in a different hook), repos: [] in .pre-commit-config.yaml is handled, and shapes that can't be safely edited produce a warning instead of writing the file back unchanged.
  • d018b7f: Fix the Husky integration overwriting an existing .husky/pre-commit hook: ultracite init ran husky init, which unconditionally replaces the hook with npm test. It now runs plain husky to set up the hooks infrastructure without touching the hook file.
  • d018b7f: Fix ultracite init destroying user files it couldn't parse or merge: unparseable tsconfig.json files are no longer replaced with a minimal config, unparseable .vscode/.zed settings are no longer overwritten wholesale, and lint-staged configs with function-valued entries are left untouched — all now warn and skip instead.
  • d018b7f: Fix re-running ultracite init on an oxlint setup silently enabling the full js-plugins preset — the previously selected JS plugins are now preserved when no new selection is made. Init also no longer flips an explicit "type": "commonjs" in package.json to "module"; it warns instead.
  • d018b7f: Fix switching linters removing storybook from the project's dependencies. It was swept into the removal set as a peer of eslint-plugin-storybook, but it's a user-facing tool a project may use independently of linting.
  • d018b7f: Fix Stylelint target generation dropping directories with a dot in their name (e.g. app.web) and producing non-matching globs from Windows-style backslash paths. Framework detection also handles negated workspace patterns (!packages/legacy) again.
  • d018b7f: Fix the CLI becoming a silent no-op (exiting 0 without linting anything) when a generic TEST environment variable is set, as is common in CI matrices. The internal test guard now uses ULTRACITE_TEST.
  • 36c7b80: Move @​typescript-eslint/utils from dependencies to devDependencies. It was accidentally shipped as a runtime dependency in 7.9.0, pulling eslint and the typescript-eslint packages into every consumer's install (including oxlint-only setups) via npm's automatic peer dependency installation. Nothing in the published package imports it — it only exists to support the workspace-internal rule-parity script.

v7.10.0

Compare Source

Minor Changes
  • cd0a36c: Add --claude and --codex flags to ultracite fix. After the normal autofix pass, remaining diagnostics are handed to the Claude Code or Codex CLI non-interactively, one agent run per affected file, with a live per-issue spinner that flips to ✓/✗ once the fix is verified by a re-lint. Fixes that don't survive verification are retried (up to 3 attempts per file) with the fresh diagnostics and feedback that the previous approach failed. Works with all three linter modes (Oxlint, Biome, ESLint); exits non-zero if any issues remain, matching the plain fix contract.

  • e089510: Scope React Doctor's framework-specific rules to per-framework add-on presets (#​752)

    The ultracite/oxlint/js-plugins preset no longer enables React Doctor's nextjs-* and TanStack (query-*, tanstack-start-*) rules for every consumer. Rules like nextjs-no-img-element and tanstack-start-no-anchor-element fire on plain <img>/<a> JSX and recommend framework replacements, which falsely errored in Vite + React and other non-Next/non-TanStack projects.

    Those rules now live in two new add-on presets:

    • ultracite/oxlint/next/js-plugins
    • ultracite/oxlint/tanstack/js-plugins

    ultracite init wires the matching add-on automatically when you select the framework together with oxlint-plugin-react-doctor. If you manage oxlint.config.ts by hand and use Next.js or TanStack, add the matching add-on preset to extends alongside js-plugins to keep those rules — or re-run npx ultracite init.

    Also fixes re-running init on a config that already extends js-plugins producing a duplicate import jsPlugins declaration.

Patch Changes
  • 3320cd8: Update Biome to 2.5.6. No stable (non-nursery) rules were added, removed, or promoted between 2.5.3 and 2.5.6, so the preset configs are unchanged.

  • 477cd6e: Update ESLint to 10.8.0 and all ESLint plugins to their latest versions. Highlights:

    • eslint-plugin-react-doctor 0.9.3: the react preset expands from 149 to 417 rules, adopting the upstream recommended set (react-router, three.js/r3f, ink, motion, remotion, zustand/valtio/mobx, and more) while excluding rules that duplicate already-enabled react, react-hooks, and jsx-a11y rules. The next preset gains nextjs-async-dynamic-api-not-awaited and nextjs-metadata-url-consistency; the tanstack preset gains tanstack-start-missing-scripts, query-floating-mutate-async, and query-no-mutation-in-effect-as-read.
    • eslint-plugin-unicorn 72: adds no-missing-local-resource, no-multiple-promise-resolver-calls, no-shorthand-property-overrides, no-transition-all, no-unnecessary-string-trim, no-useless-re-export, prefer-then-catch, and require-frontmatter-fields. CSS-only rules are excluded from the preset since they fail config validation for JS files.
    • eslint-plugin-sonarjs 4.2: adds 11 rules including no-fixed-wait-in-tests, parameterized-tests, assertions-in-test-cases, prefer-native-lodash-alternative, and explicit-test-skip.
    • typescript-eslint 8.65: @typescript-eslint/no-loop-func and @typescript-eslint/no-restricted-imports were deprecated upstream in favor of the base rules, which now apply to TypeScript files.
    • eslint-plugin-astro 3: removes astro/no-omitted-end-tags and astro/valid-compile.
    • eslint-plugin-svelte 3.22: adds no-bind-value-on-checkable-inputs and no-conflicting-module-names; no-restricted-html-elements is now off because its schema requires a user-supplied element list.
    • @angular-eslint/eslint-plugin 22.1: adds inject-at-top and prefer-service-decorator.
  • b81578b: Fix the useSortedPackageJson action not being executed by turning on assist actions for package.json-like files.

  • 9ec454a: Update oxlint to 1.76.0 and oxfmt to 0.61.0. New stable rules added to the presets: oxc/bad-match-all-arg, id-denylist, node/exports-style (core), react/function-component-definition with arrow-function components (react), and vitest/padding-around-test-blocks (vitest). node/no-top-level-await is off — top-level await is idiomatic in ESM, Astro frontmatter, and build scripts — and the ESLint preset's n/no-top-level-await is now off to match. No rules were removed or promoted out of nursery.

  • ba61c02: Fix generated oxlint.config.ts accessing plugin.name on ExternalPluginEntry without narrowing the string form, which caused a TypeScript error in projects that type-check the config (#​753)

v7.9.4

Compare Source

Patch Changes
  • f480c12: Upgrade Biome to 2.5.3 to fix the LSP scanner deadlock (#​10845) where editors get stuck on "Biome is scanning the project".
  • 1d70c40: Fail fast with an actionable message when Biome can't resolve ultracite/biome/core. Biome resolves that config out of the project's node_modules, so it errors with an opaque "module not found" whenever Ultracite isn't installed there — a state npx ultracite check / bunx ultracite check hide, because they run the CLI from a temp cache regardless. check and fix now detect it before invoking Biome and say what's actually wrong, and doctor verifies that Ultracite resolves rather than just appearing in package.json (#​750).
  • 38d10bc: Move Biome's noUnknownAttribute rule out of the core preset and into the react preset. The rule only recognises React's JSX attribute names, so projects using Solid, Svelte, Vue, or Qwik were incorrectly flagged for framework-standard attributes such as class.
  • cf723bd: Add interactive and non-interactive selection for optional Oxlint JS plugins during init.

v7.9.3

Compare Source

Patch Changes
  • dc6d760: Disable the n/no-unpublished-import rule in the ESLint core config. This rule flags imports of packages that aren't listed as published dependencies, but it produces a lot of false positives in practice, so it's now turned off.
  • 15ecfba: Fix ultracite init --linter eslint installing an unusable toolchain. The generated ESLint config imports eslint-plugin-storybook unconditionally (which requires the storybook peer) and the generated Stylelint config extends stylelint-config-standard / stylelint-config-idiomatic-order / stylelint-prettier, but none of those packages were installed — so a fresh ESLint setup failed to load with "Cannot find package 'storybook'" or "Could not find stylelint-config-standard". These four packages are now installed with the ESLint linter.
  • 2f73a41: Upgrade to oxlint 1.73.0 and oxfmt 0.58.0, and enable the new lint rules they introduce: no-unreachable-loop, unicorn/explicit-timer-delay, and unicorn/no-confusing-array-with.
  • 83b2783: Add an [astro] formatter mapping (astro-build.astro-vscode) to the oxlint VS Code editor settings generated by ultracite init, since oxfmt doesn't format .astro files.
  • d186c53: Move every JS-plugin-based rule set out of the Oxlint core and framework presets and into a single opt-in ultracite/oxlint/js-plugins preset. This covers eslint-plugin-github and eslint-plugin-sonarjs (previously in core) as well as oxlint-plugin-react-doctor (previously bundled into the react, next, and tanstack presets). The core, react, next, and tanstack presets now run entirely on Oxlint's native Rust rules, so new setups no longer install those dependencies and no longer pay the slower JS-plugin lint pass. To keep the extra ESLint-parity and React Doctor rules, install eslint-plugin-github, eslint-plugin-sonarjs, and oxlint-plugin-react-doctor and extend ultracite/oxlint/js-plugins alongside core (and your framework preset).
  • 057753e: Add performance benchmarks for ultracite check / ultracite fix across all three providers (oxlint, biome, eslint). A new CI job builds the PR and its base branch on the same runner, benchmarks them interleaved, and fails on a statistically significant regression (median ratio > 1.25x with Mann-Whitney U p < 0.05) so config changes can't silently slow the linters down again.

v7.9.2

Compare Source

Patch Changes
  • c335a1f: Add **/node_modules and **/.git to the shared ignore patterns. oxlint only skips node_modules when a .gitignore lists it, so in projects without one, ultracite fix would lint and autofix files inside node_modules — corrupting installed packages (e.g. rewriting var enum wrappers in typescript/lib/typescript.js to self-referencing const, causing "Cannot access 'Comparison' before initialization" when oxlint loads eslint-plugin-sonarjs). Fixes #​737.

v7.9.1

Compare Source

Patch Changes
  • ecd10cc: Disable sonarjs/no-implicit-dependencies and github/no-implicit-buggy-globals in the oxlint and ESLint presets. Both produce false positives through oxlint's JS plugin bridge: no-implicit-dependencies has no dependency-manifest resolution so it flags builtin (bun:test) and workspace imports as missing dependencies, and no-implicit-buggy-globals misreads module-scoped declarations such as Astro frontmatter as implicit globals.

  • c76f59d: Disable sonarjs/file-name-differ-from-class in the oxlint and ESLint presets. It fires on any file whose name differs from an exported class, which is noise for the many config and module files that export objects rather than classes.

  • 29e30ce: Fold the github and sonarjs rules into the oxlint core preset. The standalone ultracite/oxlint/github and ultracite/oxlint/sonarjs presets are removed — ultracite ships framework presets, not individual plugins. Their rules now live in ultracite/oxlint/core, so every oxlint setup gets eslint-plugin-github and eslint-plugin-sonarjs through oxlint's JS plugin bridge, matching how the ESLint preset already bundles them into core.

    This is a breaking change to generated configs: ultracite/oxlint/github and ultracite/oxlint/sonarjs no longer exist. Re-run ultracite init to regenerate oxlint.config.ts.

    Also fixed: nine sonarjs rules (async-test-assertions, hooks-before-test-cases, no-duplicate-test-title, no-empty-test-title, no-floating-point-equality, no-forced-browser-interaction, no-trivial-assertions, prefer-specific-assertions, super-linear-regex) that exist in eslint-plugin-sonarjs but that oxlint's JS plugin bridge does not register. Naming them made oxlint hard-fail config parsing, which broke ultracite fix/check for oxlint projects using the sonarjs preset. They are omitted from oxlint core (still enabled in the ESLint preset), and a test now runs oxlint against core to catch this class of regression.

    The React Doctor, github, and sonarjs plugins are installed into your project's devDependencies at init (as the ESLint plugins already were), rather than bundled as dependencies of ultracite — oxlint resolves JS plugin specifiers from the project root, so they must be installed there directly.

  • 8a4291f: Upgrade to Oxlint 1.72.0 and Oxfmt 0.57.0. Oxfmt 0.57 adds native CSS and GraphQL formatters. The five new non-nursery Oxlint rules from the 1.71/1.72 releases are already covered by the presets (node/no-sync, node/no-mixed-requires, unicorn/prefer-number-coercion, unicorn/max-nested-calls, vue/no-async-in-computed-properties). The markdown ::: container-directive fence patch (which keeps proseWrap: "never" from folding fences into prose) was regenerated against the 0.57 bundle.

v7.9.0

Compare Source

Minor Changes
  • aea7fc0: Update Biome to 2.5.2 and enable the newly-stabilized rules. This adds coverage for the rules promoted out of nursery in Biome 2.5.0, including noShadow, noUnnecessaryConditions, noUnusedInstantiation (formerly noFloatingClasses), useArrayFind, useDestructuring, useGlobalThis, useErrorCause, noNestedPromises, GraphQL validation rules, and the recommended Vue/Next.js domain rules.
  • 2687cf9: Align the ESLint and Biome presets with the oxlint preset, which is now the benchmark for rule decisions across linters. ESLint: rules that oxlint deliberately disables are now off (no-console, no-continue, id-length, new-cap, max-depth, no-implicit-coercion, no-underscore-dangle, init-declarations, n/no-sync, promise/always-return, promise/catch-or-return, import-x/no-commonjs, import-x/no-dynamic-require, import-x/no-nodejs-modules, import-x/unambiguous, import-x/no-anonymous-default-export, @typescript-eslint/explicit-member-accessibility, @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-require-imports, and the unicorn rules explicit-length-check, max-nested-calls, no-process-exit, prefer-global-this, prefer-string-raw, prefer-top-level-await); consistent-type-definitions now enforces interface instead of type, matching oxlint and Biome; no-void allows statement position to coexist with no-floating-promises; import-x/no-named-as-default is enabled; and curly and no-unexpected-multiline are re-enabled past eslint-config-prettier. Biome: noAwaitInLoops and noIncrementDecrement are now errors and the useSortedKeys assist is on (matching no-await-in-loop, no-plusplus, and sort-keys in the other presets), while useGlobalThis is off (matching unicorn/prefer-global-this).
  • 73c1993: Require ESLint 10 for ESLint setups. The plugin suite upgrade (notably eslint-plugin-unicorn 70 and eslint-plugin-astro 2) requires ESLint 10, but ultracite init still installed eslint@^9.0.0, which crashed at config load time. Init now installs eslint@^10.0.0 and @eslint/js@^10.0.0, and the presets are fixed for ESLint 10 compatibility: settings.react.version is pinned to 19.0.0 instead of "detect" (detection uses an API removed in ESLint 10), react/jsx-filename-extension and react/forward-ref-uses-ref are disabled (their implementations use removed APIs; the former is already off in the oxlint preset and the latter is covered by react-doctor/no-react19-deprecated-apis), the react config re-applies eslint-config-prettier so JSX formatting rules stay off (several crash under ESLint 10), and import-x/no-unused-modules is disabled (it is a warning-emitting no-op under ESLint 10). Note that some plugins (eslint-plugin-github, eslint-plugin-react, eslint-plugin-jsx-a11y, eslint-plugin-solid, @tanstack/eslint-plugin-start) have not yet updated their declared peer ranges to include ESLint 10 even though they work at runtime, so strict package managers may report peer dependency warnings.
  • 4cfdf3d: Add eslint-plugin-jsdoc to the ESLint preset. The oxlint preset already enforces a set of jsdoc rules, but the ESLint preset had no jsdoc coverage at all. The plugin is now installed by ultracite init for ESLint setups and enables the same rule selection the oxlint preset enforces (check-access, check-property-names, check-tag-names, empty-tags, implements-on-classes, no-defaults, and the require-* description/name/type rules), keeping the two presets in lockstep.
  • 0b8fc12: Upgrade the ESLint plugin suite and enable the new rules that ship with it. Notable bumps: eslint-plugin-unicorn 64 → 70 (adds a large batch of new correctness and quality rules), eslint-plugin-astro 1 → 2 (adds no-omitted-end-tags, now requires ESLint 10), eslint-plugin-sonarjs 4.0 → 4.1 (adds test-assertion and ReDoS rules like super-linear-regex), eslint-plugin-svelte 3.19 → 3.20 (adds no-at-const-tags), plus @typescript-eslint, eslint-plugin-import-x, eslint-plugin-n, @vitest/eslint-plugin, and others. Two Unicorn rules that were renamed are re-mapped in the config (prefer-dom-node-dataset → dom-node-dataset, prevent-abbreviations → name-replacements). Two new Unicorn rules are disabled: prefer-temporal (since Temporal still lacks broad runtime support) and no-asterisk-prefix-in-documentation-comments (it fights the conventional JSDoc comment style).
  • 4440393: Bring the oxlint preset closer to ESLint parity with two new presets that run ESLint plugins through oxlint's JS plugin support: ultracite/oxlint/github (eslint-plugin-github) and ultracite/oxlint/sonarjs (eslint-plugin-sonarjs, 187 rules — type-aware rules are excluded since the JS plugin bridge provides no type information, and no-reference-error is off because the bridge provides no globals). ultracite init now adds both presets to generated oxlint configs and installs the two plugins; existing configs are untouched until the next init, and either preset can be dropped from extends to opt out (the plugins add roughly 1–3s to a lint run for the JS runtime bridge). Rule decisions mirror the oxlint benchmark in both directions: the ESLint preset now disables sonarjs/file-header (it errored on every file), sonarjs/arrow-function-convention (fights the formatter), sonarjs/cyclomatic-complexity, sonarjs/max-lines, sonarjs/max-lines-per-function, sonarjs/nested-control-flow (duplicates of core rules the preset disables), sonarjs/shorthand-property-grouping (conflicts with sort-keys), and github/no-dataset (conflicts with unicorn/prefer-dom-node-dataset), and sets sonarjs/cognitive-complexity to 20 to match Biome's noExcessiveCognitiveComplexity. Switching linters with init no longer removes dependencies that the newly selected linter still needs.
  • f7025b1: Extend cross-linter parity to the framework presets and add an automated parity check. The oxlint react preset now explicitly lists all 102 non-nursery react/react-perf/jsx-a11y rules (previously only ~20 were configured, so most a11y and correctness rules silently never ran) and the next preset lists all 21 nextjs rules, with decisions matching the ESLint presets. The revived exhaustiveness test (the oxlint --rules markdown output it parsed is empty as of oxlint 1.72, so it was passing vacuously) also caught five newly stabilized rules which are now enabled: getter-return, no-unreachable, oxc/branches-sharing-code, unicorn/prefer-export-from, and unicorn/prefer-single-call. ESLint preset fixes that fell out of the audit: no-loss-of-precision and no-duplicate-imports are re-enabled for TypeScript files (their @typescript-eslint twins were removed in v8, leaving TS uncovered), no-duplicate-imports gets allowSeparateTypeImports to match oxlint, the react/vue configs now only re-apply the react/-vue/-prefixed entries of eslint-config-prettier so they can't clobber unrelated rules, the svelte preset keeps the formatting rules disabled that eslint-plugin-svelte's own prettier preset lists, and astro/semi is off (Prettier owns formatting). A new compare-rule-parity script runs as part of validate:configs: it resolves the effective ESLint rule sets with ESLint's own config resolution, normalizes names to oxlint's, and fails on any divergence not recorded in an explicit allowlist — currently just two entries (sonarjs/no-reference-error, unicorn/number-literal-case), both with documented reasons.
  • 223233f: Add React Doctor rules to the ESLint and Oxlint React, Next.js, and TanStack presets. This enables React Doctor's own rules — the "You Might Not Need an Effect" family (no-fetch-in-effect, no-derived-state, no-mirror-prop-effect, etc.) plus its render-performance, hydration, server-component, security, and framework-specific rules — via eslint-plugin-react-doctor and the oxlint-plugin-react-doctor JS plugin. Rules that React Doctor ports from eslint-plugin-react, eslint-plugin-react-hooks, and eslint-plugin-jsx-a11y are intentionally left off to avoid duplicate diagnostics with the plugins Ultracite already ships.
Patch Changes
  • d247ff2: Migrate stale linter and formatter configuration when switching toolchains during init. Running ultracite init now removes config files and dependencies for unselected Biome, ESLint/Prettier/Stylelint, or Oxlint/Oxfmt setups before writing the selected toolchain config.
  • e24068b: Sort package.json keys when using Biome

v7.8.4

Compare Source

Patch Changes
  • e4ddd22: Ignore .yarn directories by default
  • a1d5c06: Configure Oxfmt to never wrap prose (proseWrap: "never")
  • df709a4: Ignore .wrangler and .wrangler-dry-run output directories by default

v7.8.3

Compare Source

Patch Changes
  • c863d09: Fix automatic editor extension installation during ultracite init.

    The whole command line (e.g. code --install-extension) was passed to
    spawnSync as the executable name, which always failed with ENOENT and
    silently fell back to the "install manually" message. The command is now split
    into the binary and its arguments, so the linter extension actually installs
    for VS Code-based editors.

  • 6888129: Enable the eslint/no-await-in-loop rule as an error in the core Oxlint
    preset.

    Awaiting inside a loop forces each iteration to run sequentially, which can
    lead to serious performance issues when the asynchronous operations could
    otherwise run concurrently. Promoting this rule to an error encourages
    collecting promises and resolving them together (e.g. with Promise.all)
    instead of blocking on each one in turn.

  • 62a9b5c: Fix the generated Husky pre-commit hook's error handling and section
    replacement.

    The standalone hook script set set -e and then tried to capture the
    formatter's exit code, re-stage files, and print a failure message — but a
    non-zero formatter exit terminated the script immediately, so none of that
    ever ran. The script now captures the exit code with || FORMAT_EXIT_CODE=$?
    so files are re-staged and failures are reported with the right exit code.

    Re-running ultracite init also deleted everything from the # ultracite
    marker to the end of the hook, including commands the user added after the
    ultracite section. The section is now terminated with an explicit
    # ultracite end marker and updates replace only the section between the
    markers (legacy sections without an end marker are detected by their closing
    echo line).

  • 6608ceb: Make the lint-staged integration idempotent and respect dedicated config
    files.

    package.json was always treated as the lint-staged config because the file
    exists in every project, so ultracite init wrote the lint-staged config into
    package.json even when a dedicated .lintstagedrc.* or
    lint-staged.config.* file was present — leaving two conflicting configs.
    package.json now only counts when it actually has a lint-staged key;
    otherwise the dedicated config file is updated (or .lintstagedrc.json is
    created).

    Re-running ultracite init also appended another npx ultracite fix entry on
    every run because the merge concatenates arrays. Updates are now skipped when
    the existing config already references ultracite.

  • 4e847f7: Insert -- before script arguments in npm hook commands.

    The post-edit hook command generated for npm projects was
    npm run fix --skip=correctness/noUnusedImports, where npm consumes the
    --skip flag itself instead of forwarding it to the script — so agent hooks
    ran a plain ultracite fix, including the unused-import removal the flag
    exists to prevent mid-edit. The generated command is now
    npm run fix -- --skip=correctness/noUnusedImports, matching the documented
    form.

  • ecb0d5b: Scope the Stylelint step of ultracite check and ultracite fix (ESLint mode)
    to style files.

    Stylelint was previously given the same targets as ESLint and Prettier (or .
    when no files were passed), so it tried to parse .ts/.json files as CSS and
    failed with CssSyntaxError. Style files now pass through unchanged, directory
    targets become **/*.{css,scss,sass,less} globs, other files are dropped, and
    the step is skipped entirely when no style targets remain.
    --allow-empty-input is passed so projects without CSS still succeed.

  • 61ea0a1: Fix the project-path write guard's error message and ordering.

    The "Refusing to write through directory outside project" error interpolated
    the node:path module instead of the offending file path, printing
    [object Object]. It now reports the actual path.

    writeProjectFile also created directories (mkdir -p) before running the
    path-escape check, so directories could be created outside the project before
    the guard threw. Validation now happens first; the parent-directory check
    resolves the nearest existing ancestor so writes into not-yet-created nested
    directories still work.

v7.8.2

Compare Source

Patch Changes
  • 30971a8: Enable newly available Oxlint and Stylelint rules in the shared configs.

    For Oxlint, the core preset now enables eslint/prefer-named-capture-group,
    jsdoc/require-yields-description, node/callback-return,
    typescript/method-signature-style, and unicorn/import-style.

    The Vue preset now enables vue/component-definition-name-casing,
    vue/no-computed-properties-in-data, vue/no-deprecated-props-default-this,
    vue/no-expose-after-await, vue/no-reserved-component-names,
    vue/no-shared-component-data, vue/no-watch-after-await,
    vue/require-prop-type-constructor, vue/require-render-return,
    vue/require-slots-as-functions, vue/return-in-emits-validator,
    vue/valid-define-options, and vue/valid-next-tick.

    The Stylelint preset now enables display-notation with the short option.

v7.8.1

Compare Source

Patch Changes
  • 8335be7: Build the CLI with bun build and a tsgo type-check gate instead of tsup.
  • f747449: Fix the Oxlint TanStack preset so route files under routes/ and app/routes/ are exempt from unicorn/filename-case, matching the documented 7.8.0 behavior.
  • 092597e: Fix generated oxlint.config.ts to be pre-formatted according to oxfmt rules, so ultracite check passes immediately after ultracite init without requiring a separate format step.
  • 81da6e8: Generate agent and editor hook commands through nypm's package-manager script helper.
  • 81da6e8: Keep hyphen-prefixed file operands from being forwarded to linters as options.
astral-sh/uv (uv_build)

v0.12.13

Compare Source

Released on 2026-09-10.

Python
Enhancements
  • Verify hashes when downloading PEP 658 metadata sidecars (#​21563)
Preview features
  • Respect ty exclusions when uv check automatically selects members of a virtual workspace (#​21555)
Performance
  • Avoid full wheel downloads during resolution by reusing supported hashes from direct URL fragments when metadata is available separately (#​21279)
Bug fixes
  • Edit Windows entry-point launcher resources in memory to support Nano Server and reduce antivirus contention (#​18713)
  • Prefer core-metadata over legacy aliases in JSON index responses (#​21563)

v0.12.12

Compare Source

Released on 2026-09-09.

The executables in our macOS and Windows release archives and uv and uv_build wheels are now code-signed. macOS executables are signed with an Apple Developer ID certificate and notarized by Apple. Windows executables have timestamped Authenticode signatures from Azure Artifact Signing. This enables verification of the release publisher and binary integrity, supports publisher-based allowlisting, and should reduce security warnings and antivirus false positives.

Bug fixes
  • Exclude distributions uploaded after the exclude-newer cutoff from lockfiles and generated requirement hashes (#​21539)

v0.12.11

Compare Source

Released on 2026-09-08.

Preview features
  • Generate missing artifact hashes when exporting pylock.toml files to ensure they conform to PEP 751 (#​20146)
  • Warn when pylock.toml artifact hash tables are empty, which will be rejected in a future uv release (#​21462)
Performance
  • Speed up installs that overwrite existing files by eliminating per-file temporary directories for atomic hard-link, symlink, and reflink replacements (#​21478)
  • Speed up installs that merge copied wheels into existing environments by replacing per-file temporary directories with adjacent temporary files (#​21468)
  • Speed up local wheel installs by replacing the shared ZIP cursor lock with positioned reads (#​21500)
  • Speed up local wheel installs by reusing ZIP readers and buffers across extracted files (#​21499)
  • Avoid transitive dependency checks and unnecessary resolution when uv pip install --no-deps finds the requested packages already installed (#​21523)
Bug fixes
  • Verify source archives against hashes recorded in uv.lock before reading their metadata or running their build backends (#​21223)
  • Verify supplied hashes for registry requirements pinned with === under both --verify-hashes and --require-hashes (#​21543)
  • Apply hashes from public-version pins to matching local versions when no exact local-version hash is provided (#​21544)
  • Support PowerShell virtual environment activation from UNC paths, including WSL paths (#​19159)
  • Trim surrounding whitespace from entries in .python-version and .python-versions files (#​21529)
  • Suppress VIRTUAL_ENV mismatch warnings for uv add --no-sync, uv remove --no-sync, and uv add --frozen (#​21496)
  • Warn and continue when uv python list cannot query an interpreter (#​21498)
Documentation
  • Restore TOML syntax highlighting for exclude-newer examples (#​21534)

v0.12.10

Compare Source

Released on 2026-09-04.

Enhancements
  • Attempt to revoke short-lived PyPI trusted-publishing tokens after uv publish completes, including when publishing fails (#​21423)
Preview features
  • Omit exclude-newer-package settings for packages outside the resolution from uv.lock with the missing-exclude-newer-package-lock preview feature (#​21455)
  • Show terminal dependency cycles in uv tree --invert output (#​21404)
Performance
  • Speed up locking large workspaces with conflicts by excluding unrelated extras and dependency groups from conflict simplification (#​21399)
  • Speed up uv publish by hashing each artifact in a single blocking task and reusing the buffer across reads (#​21389)
Bug fixes
  • Prevent --locked from failing when exclude-newer-package settings differ only for packages outside the resolution (#​21454)
  • Allow uv lock --check to reuse a lockfile when an absolute exclude-newer cutoff is moved later (#​19571)
  • Allow uv lock --check to reuse a lockfile when a package-specific exclude-newer cutoff is disabled (#​21450)
  • Require an explicit --name when uv init would infer a project name reserved for a Python interpreter (#​21395)
  • Write package-specific exclude-newer cutoffs to uv.lock in a deterministic order (#​21453)

v0.12.9

Compare Source

Released on 2026-09-01.

Python
Enhancements
  • Add --no-locked and --no-frozen to disable lock modes enabled by UV_LOCKED and UV_FROZEN for a single invocation (#​21408)
  • Report the exact command-line lock-mode flag in warnings and errors (#​21402)
Performance
  • Speed up cold wheel installs by extracting each streaming ZIP archive in a single blocking task and reusing buffers across files (#​21372)
Bug fixes
  • Update async_http_range_reader to 0.11.1 to address a potential memory-safety issue when reading metadata ranges from untrusted wheels (#​21401)
  • Remove sensitive headers when redirects cross authentication realms, including same-host redirects that change URL schemes (#​21382)
  • Redact secrets in signed URLs from retry diagnostics, including nested request errors (#​21381)
  • Give --locked, --frozen, --check, and --check-exists precedence over conflicting UV_LOCKED and UV_FROZEN values (#​21396)
  • Prevent concurrent uv processes from redundantly extracting the same local or source-built wheel (#​21400)

v0.12.8

Compare Source

Released on 2026-08-31.

Enhancements
  • Warn about invalid tool directories and continue upgrading valid tools with uv tool upgrade --all (#​21368)
Preview features
  • Deduplicate identical files within and across cached wheels with the content-addressed-cache preview feature (#​21327)
  • Reduce allocations while extracting content-addressed wheels by reusing the hashing buffer across files (#​21340)
  • Speed up content-addressed cache cleanup on macOS by reading hard-link counts in bulk (#​21344)
Performance
  • Prevent concurrent uv processes from downloading and extracting the same remote wheel more than once (#​21379)
  • Speed up dependency graph construction from large lockfiles by indexing packages during traversal (#​21373)
  • Extend indexed lockfile traversal to exports, dependency trees, audits, and freshness checks (#​21377)
  • Speed up warm resolutions by reducing repeated marker interner work (#​21300)
Bug fixes
  • Do not trust hashes from direct URLs discovered only in wheel metadata when installing with --require-hashes (#​21348)
  • Use a compatible Azure Storage API version for anonymous and authenticated requests, allowing credential retries when public access is disabled (#​21366)
  • Redact Azure shared access signature (sig) query parameters from displayed URLs (#​21360)
  • Treat projects below one-level workspace member globs as standalone instead of aborting workspace discovery (#​21341)
Other changes
  • Update astral-tokio-tar to 0.7.0 and use effective sizes when tracking extracted hard links (#​21346)

v0.12.7

Compare Source

Released on 2026-08-27.

Python
  • Replace managed Python installations when upgrading to a newer build of the same version (#​21323)
Enhancements
  • Support Linux s390x, ppc64le, and loongarch64 targets for cross-platform dependency resolution (#​21313)
  • Retry downloads with configured credentials when Azure Storage denies anonymous access to an endpoint configured via UV_AZURE_ENDPOINT_URL (#​21318)
Preview features
  • Use content-based directory hashes to deduplicate extracted wheels in the cache with the content-addressed-cache preview feature (#​19693)
Bug fixes
  • Reject source archives with hash mismatches before persisting their extracted contents to the cache (#​21248)
Other changes

v0.12.6

Compare Source

Released on 2026-08-25.

Python
  • Update CPython to use OpenSSL 3.5.8 and libffi 3.4.8 #​21295)
Enhancements
  • Report cache-cleaning space savings from filesystem block allocation and avoid double-counting hard links (#​21261)
  • Limit warnings about unbounded uv_build requirements to source-distribution builds (#​21078)
  • Display byte counts below 1 KiB without a fractional part (#​21237)
Preview features
  • Add uv workspace metadata --sync --exact to remove packages outside the selected resolution (#​21117)
  • Add the artifact-hash-filtering preview feature to make uv pip compile --generate-hashes honor --only-binary and --no-binary (#​21235)
  • Respect package-specific exclude-newer cutoffs when uv check selects its ty executable (#​21227)
  • Preserve virtual-environment hints from tar-codec source-distribution errors when the base interpreter is outside a bin directory (#​21146)
Performance
  • Enable profile-guided optimization for Linux x86-64 release binaries (#​21001)
  • Enable profile-guided optimization for Windows x86-64 release binaries (#​21003)
  • Enable profile-guided optimization for macOS ARM64 release binaries (#​21002)
  • Enable profile-guided optimization for Linux ARM64 release binaries (#​21004)
  • Speed up syncing projects with many activated conflict items by reusing their encoded representation (#​21148)
Bug fixes
  • Allow explicit uv build and non-editable first-party workspace packages when no-build is enabled (#​21294)
  • Reuse configured index credentials during uv tool upgrade when the tool receipt references the same index (#​21275)
  • Ensure full 40-character Git commit pins resolve to the requested object instead of a SHA-named branch (#​21224)
  • Prevent TLS segfaults in riscv64 musl release binaries (#​21158)
  • Preserve dependencies selected by recursive extras when markers mix production and extra conditions (#​21181)
  • Preserve version constraints from transitively referenced recursive extras (#​21209)
  • Resolve repository-relative Git archive dependencies inside the checkout during the initial uv sync (#​21264)
  • Return an error instead of panicking when a bearer token cannot be encoded as an HTTP header (#​21282)
  • Do not misclassify package URLs ending in .py as local script paths (#​21144)
  • Use directory creation times consistently across libc implementations for directory cache-keys entries (#​21137)
  • Promote human-readable sizes to the next unit at rounding boundaries (#​21136)
Other changes
  • Add Python 3.15 release-candidate Docker images (#​21293)
  • Raise the minimum supported Rust version to 1.96 and update the repository toolchain to Rust 1.98 (#​21258)

v0.12.5

Compare Source

Released on 2026-08-14.

Python
  • Add CPython 3.10.21, 3.11.16, and 3.12.14 (#​21138)
  • Prefer newer versions and standard variants when selecting between equally prioritized Python interpreters (#​21134)
Enhancements
  • Simplify errors and hints for invalid editable requirements, and redact credentials in requirement URLs (#​21130)
Preview features
  • Allow --index and --default-index to select configured package indexes by name with the index-by-name preview feature (#​17455)
  • Include distribution artifact URLs and hashes in CycloneDX SBOM exports by default (#​21131)
  • Fall back to logical file sizes when using cache-physical-space on filesystems that do not support physical-space accounting (#​21133)
Bug fixes
  • Resolve relative package index paths in PEP 723 scripts against the script directory (#​21097)

v0.12.4

Compare Source

Released on 2026-08-13.

Enhancements
  • Prefer post-quantum key exchange and enable opt-in TLS diagnostics (#​21054)
  • Accept whitespace before versions in noncompliant wildcard comparisons such as Requires-Python: >= 3.5.* (#​21012)
  • Report a specific error when a PEP 723 closing tag contains trailing whitespace or other content (#​20944)
  • Omit source-span carets from diagnostics for empty PEP 508 requirements (#​21094)
Preview features
  • Add uv check --no-install-project and respect UV_NO_INSTALL_PROJECT to install dependencies without building or installing the project (#​21085)
  • Make the ty subprocess invoked by uv check honor uv's color and progress settings, including quiet mode (#​21086)
Performance
  • Speed up resolutions with long runs of unavailable package versions by coalescing gaps in the resolver's version ranges (#​20804)
  • Speed up Simple API parsing by deserializing PyPI and Pyx file metadata directly (#​21041)
Bug fixes
  • Use windowed pythonw.exe launchers for virtual environments created from managed Python minor-version links (#​19235)
  • Allow uv lock to proceed when .venv is an unusable project environment (#​21068)
  • Respect fork-strategy when ordering forks created from environments or existing lockfile resolution-markers (#​21000)
  • Preserve consecutive wildcard Python minor-version exclusions such as !=3.11.*, !=3.12.* in uv.lock (#​21045)
  • Preserve inline comments on the final item in dependency arrays when uv add updates it (#​21008)
  • Recover from stale base-interpreter cache metadata when an existing virtual environment exposes a version mismatch (#​21073)
  • Prevent interpreter cache reuse across different PYTHONEXECUTABLE and __PYVENV_LAUNCHER__ overrides (#​21075)
  • Show standard styling, usage guidance, and line termination for invalid uv version --bump values (#​21076)

v0.12.3

Compare Source

Released on 2026-08-07.

Python
Preview features
  • Add --output-format to select automatic, human-readable, or raw-byte output for uv cache size (#​20992)
  • Preserve JSON output from uv workspace metadata --quiet while suppressing diagnostics (#​20991)
  • Reduce memory usage for large workspaces by streaming uv workspace metadata JSON output (#​20990)
Performance
  • Reduce Linux startup latency by initializing the workspace cache before spawning another thread (#​20989)
  • Reuse compiled workspace exclusion patterns during workspace discovery (#​20988)
  • Speed up conflict-heavy resolutions by avoiding materialized range complements (#​20982)
  • Avoid slow procfs reads during Python interpreter discovery on Linux (#​20987)
Documentation
  • Add PEP 740 attestations to the GitHub Actions publishing example (#​20986)
  • Restrict the GitHub Actions publishing example to Python version tags (#​20973)
  • Correct --python-pin to --pin-python in the uv init --bare example (#​20876)

v0.12.2

Compare Source

Released on 2026-08-05.

Python
Enhancements
  • Ensure diagnostic hints end with a newline to prevent malformed terminal output (#​20959)
Preview features
  • Audit one or all installed tools with uv tool audit (#​20921)
  • Report physically reclaimed disk space during cache cleanup with the cache-physical-space preview feature (#​20925)
Configuration
  • Add UV_RUN_RLIMIT_NOFILE to set the open-file limit for commands launched by uv run (#​20926)
Performance
  • Speed up uv.lock parsing for wheel entries (#​20881)
  • Speed up uv.lock parsing for source distribution entries (#​20882)
  • Speed up filename extraction from distribution URLs (#​20879)
  • Reduce filesystem metadata lookups during bytecode compilation (#​20928)
  • Reuse file metadata when building source distributions (#​20927)
Bug fixes
  • Preserve compatibility with older uv versions when recording artifact sizes in cached wheels and source distributions (#​20963)
  • Avoid including workspace-root default dependency groups when syncing or exporting a selected workspace member unless explicitly requested (#​20930)
Documentation
  • Separate build and publish jobs in the GitHub Actions publishing guide (#​20946)
  • Ensure the GitHub Actions publishing example waits for the build job to finish (#​20957)
  • Correct typos in the Docker integration guide (#​20970)

v0.12.1

Compare Source

Released on 2026-09-15.

This release fixes a regression in 0.12.14 that lead to rejecting valid installation commands such as using
uv pip install --system in python:* docker images or when using uv pip install --target .. (#​21699)

Performance
  • Speed up cold-cache resolution and HTTP cache revalidation by batching cache writes (#​21675)
Bug fixes
  • Revert "Reject symlinked wheel installation destinations" (#​21699)

v0.12.0

Compare Source

Released on 2026-07-28.

Since we released uv 0.11.0 in March, we've accumulated changes that improve correctness, safety, and compatibility with specifications, but could break some workflows. This release contains those changes; many have been marked as breaking out of an abundance of caution.

We expect most users to be able to upgrade without making changes.

There are no breaking changes to the configuration of the uv build backend. If your [build-system] table includes an upper bound on uv_build, update it to allow uv_build 0.12, e.g., uv_build>=0.11.32,<0.13.

Breaking changes
  • Define build systems by default with uv init (#​19197)

    Projects created with uv init now declare a build system and are packaged by default. This was the default project layout all the way back in v0.3, but we found that the use of the hatchling build system was confusing to newcomers and consequently dropped use of a build system by default in v0.4. Since then, we've created our own build system (uv_build) with tight integration with uv and are excited to restore the default to a best-practice project layout.

    Previously, uv init example created an unpackaged layout containing main.py and a pyproject.toml without a build system. The project could declare dependencies but was not itself installed into its virtual environment.

    Now, uv init example defines a [build-system] using uv_build, places application source code in src/example, and includes a [project.scripts] entry named example. Defining a build system allows the project to be imported from tests or other code, installed as a dependency, and run as a command:

    $ uv init example
    $ cd example
    $ uv run example
    Hello from example!
    

    Existing projects are unaffected. Use uv init --no-package example to create the previous unpackaged layout without a build system.

    See the project creation documentation for more details.

    This stabilizes the packaged-init preview feature.

  • Reject unsupported source distribution and wheel archive formats (#​18927)

    PEP 625 requires source distributions to use .tar.gz archives. Previously, uv also accepted legacy formats such as .tar.bz2 and .tar.xz. Those formats are now rejected, including when referenced by an existing lockfile. Legacy .zip source distributions remain supported for backwards compatibility.

    Wheels and other ZIP archives can no longer contain entries compressed with bzip2, LZMA, or XZ. Entries must use the stored, DEFLATE, or zstd compression methods.

    Removing support for uncommon compression methods reduces uv's compression dependencies and the attack surface exposed when processing untrusted packages.

    You cannot opt out of this behavior. If you depend on a legacy source distribution that uses an unsupported format, we recommend rebuilding it as a .tar.gz archive and regenerating any lockfile containing references to the legacy archive.

  • Reject wheel files that could replace the Python interpreter (#​20748, #​20749)

    uv already rejected wheel entry points named python, but case variants such as Python were still accepted. On case-insensitive filesystems, including common macOS and Windows setups, these entry points could overwrite the virtual environment's interpreter.

    Wheels could also place interpreter files in their .data/scripts directory or in paths such as .data/data/bin/python, bypassing the entry-point check and replacing the interpreter during installation.

    uv now rejects case-insensitive variants of reserved interpreter names and wheel data files that would be installed over an interpreter. This includes names such as Python, python.py, and Python.exe, along with other reserved interpreter names and their versioned variants.

    You cannot opt out of these checks. Rename conflicting entry points or wheel data files and rebuild the affected wheel.

  • Prefer stable releases before falling back to pre-releases (#​19993)

    A dependency can introduce a pre-release requirement after resolution starts. uv previously required each package's pre-release eligibility to be known before resolution began: the default if-necessary-or-explicit mode allowed them for direct requirements that explicitly requested a pre-release, or for packages that only published pre-releases.

    This meant that a pre-release requirement discovered in a dependency's metadata, e.g., example>=2.0.0b1, would fail to resolve even when a compatible pre-release existed. To resolve it, you had to add that dependency as a direct requirement or allow pre-releases across your entire dependency graph.

    The default mode is now if-necessary. uv tries stable candidates first and falls back to pre-releases when no stable candidate satisfies the active constraints. Like pip, uv now supports pre-release requirements discovered transitively, but can select different versions than previous uv releases when both stable and pre-release candidates are available.

    You can opt out of automatic pre-release selection with --prerelease disallow. Alternatively, --prerelease allow considers pre-releases without first preferring stable releases, and --prerelease explicit only allows them for direct requirements that mention a pre-release.

    The old if-necessary-or-explicit mode distinguished between explicitly requested pre-releases and packages with no stable releases. That distinction is unnecessary now that if-necessary handles both cases, including transitive requirements. The old name remains available as an alias but is deprecated and will be removed in a future release.

  • Respect --require-hashes directives in requirements.txt (#​19336)

    Previously, uv pip install and uv pip sync warned about --require-hashes inside a requirements.txt file but still installed dependencies without checking their hashes. Now, the directive enables hash-checking mode, just as if --require-hashes had been passed on the command line.

    For example, this requirements file is no longer accepted because the requirement is neither pinned nor hashed:

    --require-hashes
    anyio
    

    You cannot opt out while the directive is present. Pin every requirement with == and provide its hash, or remove --require-hashes if hash checking is not intended.

  • Reject MD5-only hashes in hash-checking mode (#​20758)

    Previously, uv pip install --require-hashes and uv pip sync --require-hashes accepted requirements whose only available digest used MD5. MD5 is not collision-resistant, so relying on it undermined installations that require hash verification and differed from pip's behavior.

    Hash-checking mode now requires at least one secure digest for every requirement. For example, the following requirement is rejected unless a secure hash, such as SHA-256, is also supplied:

    anyio==4.0.0 --hash=md5:420d85e19168705cdf0223621b18831a
    

    A secure hash can be supplied directly on the requirement or in a matching constraints file. Ordinary hash verification without --require-hashes continues to support MD5.

    You cannot opt out while hash checking is required. Regenerate affected hashes with SHA-256 or another supported secure hash.

  • Reject invalid pylock.toml files and artifacts (#​20402, #​20440, #​20443)

    uv now validates additional requirements from the pylock.toml specification:

    • The packages array must be present. Previously, uv interpreted a missing array as an empty lockfile, so uv pip sync could uninstall an environment instead of rejecting malformed input. An explicitly empty packages = [] array remains valid.
    • Lockfile filenames must be pylock.toml or a single-name variant such as pylock.dev.toml. Names such as pylock..toml and pylock.foo.bar.toml are rejected.
    • If a wheel, source distribution, or other artifact declares a size, the downloaded or cached artifact must match. Previously, an incorrect size was accepted when the hash was correct. Sizes reported by package indexes remain advisory.

    You cannot opt out of these checks. Regenerate malformed lockfiles, rename invalid filenames, and either correct or remove an incorrect optional size value.

  • Honor explicit certificate overrides even when no certificates can be loaded (#​20741, #​20767)

    Previously, uv ignored SSL_CERT_FILE or SSL_CERT_DIR values that pointed to missing or inaccessible paths, empty files or directories, or sources without valid certificates. Instead, it fell back to its default trust roots, potentially allowing HTTPS connections that the configured override was intended to reject.

    Now, any non-empty SSL_CERT_FILE or SSL_CERT_DIR value replaces uv's default certificate roots, even when no valid certificates can be loaded. In that case, HTTPS requests fail because no certificates are trusted. This applies to package downloads and remote scripts, including GitHub Gists.

    Fix or unset the certificate override. Unsetting it restores the default trust store; empty environment-variable values continue to be ignored.

  • Support pip-compatible --cert handling in uv pip (#​20418)

    The uv pip interface now accepts --cert <path>, e.g.:

    $ uv pip install --cert ./company-ca.pem example
    

    As in pip, the provided PEM bundle replaces all other certificate sources for that invocation, including system certificates and SSL_CERT_FILE or SSL_CERT_DIR. This change has no effect unless you pass --cert. Include the necessary certificate authorities in the bundle.

    --cert is only supported by uv pip commands; other uv commands continue to use their existing certificate configuration.

  • Discover projects relative to the script passed to uv run (#​20225)

    Previously, uv run project/script.py discovered its project from the current directory, even when the script belonged to another project. uv now starts project and workspace discovery from the script's directory instead.

    For example, running uv run other-project/script.py now uses other-project and its dependencies. This fixes scripts that previously failed because their own dependencies were not installed, but can select a different environment than before.

    You can opt out of script-relative discovery by selecting a project explicitly, e.g., uv run --project . other-project/script.py.

    This stabilizes the target-workspace-discovery preview feature.

  • Require --force before clearing a directory that is not a virtual environment (#​20225)

    uv venv --clear previously removed any existing target directory, even if it was not a virtual environment. uv emitted a warning but still deleted the directory and its contents. Now, uv refuses to clear directories that do not contain a virtual environment.

    You can opt out of this safety check by explicitly passing --force, e.g., uv venv --clear --force ./not-a-virtualenv.

    This stabilizes the venv-safe-clear preview feature.

  • Reject --project when initializing a project (#​20225)

    --project selects an existing project, so it is not meaningful when initializing a new one. Previously, uv init --project example warned and initialized example anyway; if a positional path was also provided, --project was ignored.

    This usage is now an error. Use uv init example to initialize a project at the requested path, or uv init --directory example to change the working directory first.

    This stabilizes the init-project-flag preview feature.

  • Reject missing or invalid --project paths (#​20225)

    uv previously warned when --project referred to a missing directory or a file other than pyproject.toml, but then attempted to continue. This could produce confusing errors later or run against an unintended project.

    Now, uv run --project missing python fails immediately instead of continuing. You cannot opt out of this behavior. Create the directory first or select an existing project. Passing --project path/to/pyproject.toml remains supported and selects the file's parent directory.

    This stabilizes the project-directory-must-exist preview feature.

  • Skip distributions with non-normalized filenames when publishing (#​20225)

    Distribution filenames must use normalized package names and versions. For example, a wheel for version 1.01.0 should be named example-1.1.0-py3-none-any.whl, not example-1.01.0-py3-none-any.whl.

    Previously, uv publish warned about non-normalized filenames but still attempted to upload them. It now skips the affected wheels and source distributions instead.

    You cannot opt out of this behavior. Rebuild distributions with normalized filenames before publishing.

    This stabilizes the publish-require-normalized preview feature.

  • Classify Conda environments named base and root by their paths (#​20225)

    Conda environments named base or root were previously assumed to be the base Conda environment, even when they were ordinary child environments. uv now recognizes child Conda environments named base or root based on their paths, as it already does for other names.

    You can opt out of automatic interpreter selection by requesting an interpreter explicitly with --python /path/to/python.

    This stabilizes the special-conda-env-names preview feature.

  • Reject broken .venv symlinks during environment discovery (#​20433)

    Previously, uv could ignore a broken .venv symlink and continue searching parent directories for another virtual environment. As a result, commands such as uv pip install could unexpectedly modify an unrelated ancestor environment.

    uv now stops at a broken .venv symlink and reports its exact path. Errors encountered while reading virtual environment metadata, including permission failures, are also reported immediately instead of being ignored.

    You cannot opt out of this behavior. Repair or remove the broken .venv symlink and correct any permissions that prevent uv from inspecting the environment.

  • Reinstall matching installed Python patch versions instead of upgrading implicitly (#​20659)

    Before Python upgrades were supported, uv python install 3.12 --reinstall doubled as a way to install the latest Python 3.12 patch release. Now that --upgrade is available, --reinstall reinstalls the matching patch releases that are already present.

    For example, if Python 3.12.6 and 3.12.7 are installed, uv python install 3.12 --reinstall reinstalls both versions instead of installing the latest available 3.12 release.

    You can recover the previous upgrade behavior with uv python install 3.12 --upgrade. Combine --upgrade --reinstall to reinstall only the latest patch.

  • Require --upgrade-group to name an existing dependency group (#​18957)

    Previously, uv lock --upgrade-group docs silently succeeded even if no docs dependency group existed. uv now validates the requested group against the project, its workspace members, and workspace-level dependency groups.

    You cannot opt out of this behavior. Correct the group name or add it to [dependency-groups]. Legacy tool.uv.dev-dependencies still satisfies --upgrade-group dev.

  • Resolve relative indexes and find-links against --directory (#​20740)

    The --directory option changes the directory in which uv operates. Previously, relative index and find-links paths supplied on the command line were still resolved against the original working directory.

    uv now resolves --index, --default-index, --index-url, --extra-index-url, and --find-links relative to the directory selected by --directory. For example:

    $ uv add --directory project --index ./packages example
    

    This now uses project/packages instead of ./packages in the original working directory. Absolute paths and indexes loaded from configuration files are unaffected.

    To preserve the previous target, pass an absolute path or adjust the relative path, e.g., --index ../packages.

  • Preserve absolute paths provided to uv add (#​18402)

    uv add previously converted every local dependency into a project-relative path, even when the original request used an absolute path or a literal file:// URL. It now preserves the form of the request in pyproject.toml and uv.lock:

    $ uv add ../library             # remains relative
    $ uv add /projects/library      # remains absolute
    

    Absolute paths make a project less portable. Use a relative path to avoid recording an absolute path. URLs containing expanded variables retain their existing relative-path behavior.

  • Remove older PyPy distributions that are only available as bzip2 archives (#​20423)

    Older PyPy patch releases that are only distributed as .tar.bz2 archives are no longer available through uv python install. These releases require unsupported bzip2 archives.

    The latest PyPy release for each supported Python minor version is available as a gzip-compressed archive and remains supported. For example, uv python list 3.10 --all-versions still includes the latest PyPy 3.10 release, but older bzip2-only patch releases are omitted.

    You cannot opt out of this behavior. Request a newer PyPy patch release instead.

  • Omit excluded-package comments when annotations are disabled (#​20085)

    uv pip compile --no-annotate suppresses comments describing the generated requirements file. Previously, a footer listing packages excluded with --unsafe-package was still included, even though annotations were disabled. That footer is now omitted.

    You can recover the footer by removing --no-annotate.

Stabilizations
  • TOML 1.0-compatible source distributions (#​20225)

    uv_build now writes a TOML 1.0-compatible pyproject.toml when building source distributions, allowing older Python build frontends to consume projects that use newer TOML syntax. The original project file remains available in the archive as pyproject.toml.orig.

    This stabilizes the toml-backwards-compatibility preview feature.

  • Automatic open-file limit adjustment on Unix (#​20225)

    On Linux and macOS, uv now attempts to raise the soft open-file limit at startup toward the hard limit, capped at 1,048,576 descriptors. The new limit also applies to subprocesses and reduces failures caused by running out of file descriptors. If the limit cannot be raised, uv continues running with the existing limit.

    This stabilizes the adjust-ulimit preview feature.

Preview features
  • Allow uv upgrade to target multiple packages, upgrade all production dependencies, and exclude selected dependencies (#​20338)
Bug fixes
  • Include extras activated by dependency groups when evaluating conflicts (#​20237)

Configuration

📅 Schedule: (in timezone Europe/Warsaw)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Mend Renovate CLI.

This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [@biomejs/biome](https://biomejs.dev) ([source](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome)) | [`2.4.15` → `2.5.13`](https://renovatebot.com/diffs/npm/@biomejs%2fbiome/2.4.15/2.5.13) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@biomejs%2fbiome/2.5.13?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@biomejs%2fbiome/2.4.15/2.5.13?slim=true) | | [ultracite](https://www.ultracite.ai/) ([source](https://github.com/haydenbleasel/ultracite)) | [`7.8.0` → `7.11.1`](https://renovatebot.com/diffs/npm/ultracite/7.8.0/7.11.1) | ![age](https://developer.mend.io/api/mc/badges/age/npm/ultracite/7.11.1?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/ultracite/7.8.0/7.11.1?slim=true) | | [uv_build](https://pypi.org/project/uv/) ([source](https://github.com/astral-sh/uv), [changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)) | `>=0.11.14,<0.12.0` → `>=0.12.13,<0.13.0` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/uv-build/0.12.13?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/uv-build/0.11.33/0.12.13?slim=true) | --- ### Release Notes <details> <summary>biomejs/biome (@&#8203;biomejs/biome)</summary> ### [`v2.5.13`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#2513) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.12...@biomejs/biome@2.5.13) ##### Patch Changes - [#&#8203;11379](https://github.com/biomejs/biome/pull/11379) [`07a0073`](https://github.com/biomejs/biome/commit/07a0073c1e1b1de323292968b8988cc6f79ec5c7) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the nursery rule [`useLayeredStyles`](https://biomejs.dev/linter/rules/use-layered-styles/), which enforces that style rules are defined within a cascade layer and import rules to import its styles into a cascade layer. ```css /* Invalid */ @import 'foo.css'; .my-style { color: red; } /* Valid */ @import 'foo.css' layer(base); @layer base { .my-style { color: red; } } ``` - [#&#8203;11667](https://github.com/biomejs/biome/pull/11667) [`e997900`](https://github.com/biomejs/biome/commit/e997900c3eaf9d5efaf1ca12a067a962e1a04d0b) Thanks [@&#8203;devtechedge](https://github.com/devtechedge)! - Added the nursery rule [`useBetterDomTraversing`](https://biomejs.dev/linter/rules/use-better-dom-traversing), which prefers `.firstChild`, `.firstElementChild`, `.closest()`, and merged `.querySelector()` calls over positional DOM traversal. ```js element.childNodes[0]; element.children[0]; element.parentElement.parentElement; element.querySelector("a").querySelector("b"); ``` - [#&#8203;11620](https://github.com/biomejs/biome/pull/11620) [`20e513a`](https://github.com/biomejs/biome/commit/20e513af6fb0127854f4eb5cb9edee0f20d1b543) Thanks [@&#8203;jakeleventhal](https://github.com/jakeleventhal)! - Fixed [#&#8203;11610](https://github.com/biomejs/biome/issues/11610), [#&#8203;11611](https://github.com/biomejs/biome/issues/11611), [#&#8203;11612](https://github.com/biomejs/biome/issues/11612), [#&#8203;11615](https://github.com/biomejs/biome/issues/11615), and [#&#8203;11616](https://github.com/biomejs/biome/issues/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`](https://biomejs.dev/linter/rules/use-regexp-exec), [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises), [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises), [`useNullishCoalescing`](https://biomejs.dev/linter/rules/use-nullish-coalescing), and [`noUnsafePlusOperands`](https://biomejs.dev/linter/rules/no-unsafe-plus-operands). - [#&#8203;11657](https://github.com/biomejs/biome/pull/11657) [`e322040`](https://github.com/biomejs/biome/commit/e32204014687469e6c6f3684d32caf56311cc118) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;7495](https://github.com/biomejs/biome/issues/7495): [`noUselessConstructor`](https://biomejs.dev/linter/rules/no-useless-constructor/) 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. - [#&#8203;11670](https://github.com/biomejs/biome/pull/11670) [`4969ee1`](https://github.com/biomejs/biome/commit/4969ee1d73b48615f46f024539cfdb847f07064d) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;7076](https://github.com/biomejs/biome/issues/7076): [`useAriaPropsForRole`](https://biomejs.dev/linter/rules/use-aria-props-for-role) and [`useFocusableInteractive`](https://biomejs.dev/linter/rules/use-focusable-interactive) no longer report non-focusable elements with `role="separator"`. A separator with an explicit `tabIndex` or `tabindex` still requires `aria-valuenow`. - [#&#8203;11627](https://github.com/biomejs/biome/pull/11627) [`23aad6d`](https://github.com/biomejs/biome/commit/23aad6df8f71bd9b134633c43d2334771687d10d) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;6571](https://github.com/biomejs/biome/issues/6571) so Grit plugins can capture and inspect multiple named import specifiers. - [#&#8203;11631](https://github.com/biomejs/biome/pull/11631) [`00dbd3a`](https://github.com/biomejs/biome/commit/00dbd3a30489617d5bb55466006ac9977612a23b) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - 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. - [#&#8203;11628](https://github.com/biomejs/biome/pull/11628) [`a2f8ff7`](https://github.com/biomejs/biome/commit/a2f8ff7a1eb01f5c91e7154937e17f761863e3bc) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`noXorAsExponentiation`](https://biomejs.dev/linter/rules/no-xor-as-exponentiation/), which reports the bitwise XOR operator `^` between two decimal integer literals, where the exponentiation operator `**` was likely intended. ```js const kibibyte = 2 ^ 10; // 8, not 1024 ``` - [#&#8203;11670](https://github.com/biomejs/biome/pull/11670) [`4969ee1`](https://github.com/biomejs/biome/commit/4969ee1d73b48615f46f024539cfdb847f07064d) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;7192](https://github.com/biomejs/biome/issues/7192): [`noUnusedPrivateClassMembers`](https://biomejs.dev/linter/rules/no-unused-private-class-members/) now considers compound assignments such as `??=` to read and use private class members. - [#&#8203;11676](https://github.com/biomejs/biome/pull/11676) [`840a52a`](https://github.com/biomejs/biome/commit/840a52ad14b027e21661a9121b316ccac139d736) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11672](https://github.com/biomejs/biome/issues/11672) and [#&#8203;11671](https://github.com/biomejs/biome/issues/11671) by disabling the experimental capitalized-call and effect-dependency checks in [`useReactCompiler`](https://biomejs.dev/linter/rules/use-react-compiler/), 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. - [#&#8203;11660](https://github.com/biomejs/biome/pull/11660) [`49485ed`](https://github.com/biomejs/biome/commit/49485eda65813e5b7e2be68cdd56ffd90674f713) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;11653](https://github.com/biomejs/biome/issues/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. - [#&#8203;11664](https://github.com/biomejs/biome/pull/11664) [`9a73b9c`](https://github.com/biomejs/biome/commit/9a73b9cc4bb1000336dc25704546f4d63a9bb326) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Improved the performance of [`useRegexpExec`](https://biomejs.dev/linter/rules/use-regexp-exec/). - [#&#8203;11661](https://github.com/biomejs/biome/pull/11661) [`5341b3f`](https://github.com/biomejs/biome/commit/5341b3fb9c7bae8ce2426d32e6e72aed9637a82f) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;7479](https://github.com/biomejs/biome/issues/7479). [`noUnusedVariables`](https://biomejs.dev/linter/rules/no-unused-variables/) now treats Unicode escapes in identifiers as the same binding as their decoded spelling. - [#&#8203;11630](https://github.com/biomejs/biome/pull/11630) [`62e1fc5`](https://github.com/biomejs/biome/commit/62e1fc59621b6ab5c3988ae36b6591180e07d08f) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed the HTML formatter inserting whitespace between adjacent Svelte expressions when their combined length exceeds the line width. ```diff <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> ``` - [#&#8203;11658](https://github.com/biomejs/biome/pull/11658) [`ed4bfa4`](https://github.com/biomejs/biome/commit/ed4bfa4a1de63241a7c3586ff12d7f990cf84303) Thanks [@&#8203;fredrikblau](https://github.com/fredrikblau)! - Fixed [#&#8203;11644](https://github.com/biomejs/biome/issues/11644): [`useHeadingContent`](https://biomejs.dev/linter/rules/use-heading-content/) no longer reports headings that render their text with a directive: `set:html` and `set:text` in Astro files, `v-html` and `v-text` in Vue files. ```astro <h1 set:html={heading} /> <h2 set:text={heading}></h2> ``` ```vue <template> <h1 v-html="heading"></h1> <h2 v-text="heading"></h2> </template> ``` - [#&#8203;11613](https://github.com/biomejs/biome/pull/11613) [`47d7383`](https://github.com/biomejs/biome/commit/47d7383d049b36ff8eaba50912176928143dd9e9) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Improved the performance of Biome Formatter up to \~50% in some cases. - [#&#8203;11655](https://github.com/biomejs/biome/pull/11655) [`fd8fc74`](https://github.com/biomejs/biome/commit/fd8fc741ee2b77b3b127859fabc7a29b19e1fb0b) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;6974](https://github.com/biomejs/biome/issues/6974), where [`noUnusedPrivateClassMembers`](https://biomejs.dev/linter/rules/no-unused-private-class-members/) incorrectly reported TypeScript private constructor properties read through object destructuring from `this` as unused. - [#&#8203;11618](https://github.com/biomejs/biome/pull/11618) [`21a10cf`](https://github.com/biomejs/biome/commit/21a10cfcac4db8044e8bff6b24d9b1e197c2b343) Thanks [@&#8203;siketyan](https://github.com/siketyan)! - Fixed [#&#8203;11605](https://github.com/biomejs/biome/issues/11605): Type inference now infers the type of an unannotated callback parameter from the signature of the function the callback is passed to, and honours explicit type arguments on call expressions. This improves type-aware analysis for [`noBaseToString`](https://biomejs.dev/linter/rules/no-base-to-string/), [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/), [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/), [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises/), [`noUnnecessaryConditions`](https://biomejs.dev/linter/rules/no-unnecessary-conditions/), [`noUnsafePlusOperands`](https://biomejs.dev/linter/rules/no-unsafe-plus-operands/), [`noUselessTypeConversion`](https://biomejs.dev/linter/rules/no-useless-type-conversion/), [`useArrayFind`](https://biomejs.dev/linter/rules/use-array-find/), [`useArraySortCompare`](https://biomejs.dev/linter/rules/use-array-sort-compare/), [`useAwaitThenable`](https://biomejs.dev/linter/rules/use-await-thenable/), [`useDisposables`](https://biomejs.dev/linter/rules/use-disposables/), [`useExhaustiveSwitchCases`](https://biomejs.dev/linter/rules/use-exhaustive-switch-cases/), [`useIncludes`](https://biomejs.dev/linter/rules/use-includes/), [`useNullishCoalescing`](https://biomejs.dev/linter/rules/use-nullish-coalescing/), [`useRegexpExec`](https://biomejs.dev/linter/rules/use-regexp-exec/), and [`useStringStartsEndsWith`](https://biomejs.dev/linter/rules/use-string-starts-ends-with/). For example, `noFloatingPromises` can now detect Promises reached through such parameters: ```ts interface Context { doSomething(): Promise<void>; } declare function test(callback: (ctx: Context) => Promise<void>): void; test(async (ctx) => { ctx.doSomething(); // now reported as a floating promise }); ``` - [#&#8203;11698](https://github.com/biomejs/biome/pull/11698) [`b019982`](https://github.com/biomejs/biome/commit/b019982bfbf8a9db58bd16b1e5e1a241128540d4) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Fixed parsing of unquoted CSS URLs beginning with `@` or `!`, such as `url(@/assets/icon.svg)` and `url(!font.woff2)`. Preserved escaped and non-ASCII whitespace in raw URLs during formatting. ```diff -background-image: url(image\); +background-image: url(image\ ); ``` - [#&#8203;11622](https://github.com/biomejs/biome/pull/11622) [`c23e4c7`](https://github.com/biomejs/biome/commit/c23e4c7e7a33d3f00863d80be663678af8c2a073) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the nursery rule [`noUnsafeIframeSandbox`](https://biomejs.dev/linter/rules/no-unsafe-iframe-sandbox/), which reports `iframe` elements whose `sandbox` attribute combines `allow-scripts` and `allow-same-origin`, since that combination lets the embedded document remove its own sandboxing. ```jsx <iframe src="https://example.com" sandbox="allow-scripts allow-same-origin" /> ``` - [#&#8203;11606](https://github.com/biomejs/biome/pull/11606) [`de0528f`](https://github.com/biomejs/biome/commit/de0528f940ea41b798816e1923b2b51ffcd0b473) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the recommended [`noSvelteAtHtmlTags`](https://biomejs.dev/linter/rules/no-svelte-at-html-tags) nursery rule, which reports Svelte `{@html}` tags that render unescaped HTML. - [#&#8203;11670](https://github.com/biomejs/biome/pull/11670) [`4969ee1`](https://github.com/biomejs/biome/commit/4969ee1d73b48615f46f024539cfdb847f07064d) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;6782](https://github.com/biomejs/biome/issues/6782): GritQL plugins now match captured JSX component names against code snippets such as `React.Fragment`. - [#&#8203;11687](https://github.com/biomejs/biome/pull/11687) [`09d97d9`](https://github.com/biomejs/biome/commit/09d97d973b522c6bd95e6d26006cb4b3a221396d) Thanks [@&#8203;hori-design](https://github.com/hori-design)! - Fixed [#&#8203;11678](https://github.com/biomejs/biome/issues/11678): [`useReactCompiler`](https://biomejs.dev/linter/rules/use-react-compiler/) no longer panics on files that contain non-ASCII characters. This bumps the React Compiler version. - [#&#8203;11595](https://github.com/biomejs/biome/pull/11595) [`a64d757`](https://github.com/biomejs/biome/commit/a64d7572d5684f3555be5dc02eb1d29a16f290dc) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery Vue-domain rule [`useVueBaseImport`](https://biomejs.dev/linter/rules/use-vue-base-import/) rule, which enforces importing Vue APIs from `vue` instead of internal `@vue/*` packages. - [#&#8203;11675](https://github.com/biomejs/biome/pull/11675) [`353cbae`](https://github.com/biomejs/biome/commit/353cbae47056f8e03b27d1d9b69e165b5b72f122) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [`useReactCompiler`](https://biomejs.dev/linter/rules/use-react-compiler/) silently producing no diagnostics in WebAssembly builds, including the playground. - [#&#8203;11625](https://github.com/biomejs/biome/pull/11625) [`ea20e5a`](https://github.com/biomejs/biome/commit/ea20e5a4640b4455cd12e0eb6ffaa590803c67a2) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Improved linting performance for large CSS and JSON files. - [#&#8203;11670](https://github.com/biomejs/biome/pull/11670) [`4969ee1`](https://github.com/biomejs/biome/commit/4969ee1d73b48615f46f024539cfdb847f07064d) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;7527](https://github.com/biomejs/biome/issues/7527): suppression actions for diagnostics emitted on comments are now inserted before the diagnostic comment. In particular, suppressing [`noTsIgnore`](https://biomejs.dev/linter/rules/no-ts-ignore/) now places the `biome-ignore` comment before `@ts-ignore`. - [#&#8203;11655](https://github.com/biomejs/biome/pull/11655) [`fd8fc74`](https://github.com/biomejs/biome/commit/fd8fc741ee2b77b3b127859fabc7a29b19e1fb0b) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;8629](https://github.com/biomejs/biome/issues/8629), where [`noUnusedPrivateClassMembers`](https://biomejs.dev/linter/rules/no-unused-private-class-members/) incorrectly reported used private TypeScript method overload signatures as unused. - [#&#8203;11669](https://github.com/biomejs/biome/pull/11669) [`579f401`](https://github.com/biomejs/biome/commit/579f401b0a97760db99d64b97b2bc29ab20e3f8a) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Improved the performance of [`noExcessiveLinesPerFile`](https://biomejs.dev/linter/rules/no-excessive-lines-per-file/) when `skipBlankLines` is `false`. ### [`v2.5.12`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#2512) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.11...@biomejs/biome@2.5.12) ##### Patch Changes - [#&#8203;11440](https://github.com/biomejs/biome/pull/11440) [`b88f1ea`](https://github.com/biomejs/biome/commit/b88f1ea368c727ff8ebeddcaf9448f6ddc7c4878) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed Astro attribute expressions rejecting TypeScript and JSX syntax that is accepted in text expressions. ```astro <Component icon={<Icon />} count={total as number} onSelect={(e: Event) => e} /> ``` - [#&#8203;11440](https://github.com/biomejs/biome/pull/11440) [`b88f1ea`](https://github.com/biomejs/biome/commit/b88f1ea368c727ff8ebeddcaf9448f6ddc7c4878) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed Astro attribute names being split on `:` and `.` inside an expression, such as `{x && <button x-on:keyup.enter={go} client:load.foo />}`. - [#&#8203;11440](https://github.com/biomejs/biome/pull/11440) [`b88f1ea`](https://github.com/biomejs/biome/commit/b88f1ea368c727ff8ebeddcaf9448f6ddc7c4878) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed a bare `>` in the children of an Astro expression being treated as markup, such as `{x && <div>a > b</div>}`. - [#&#8203;11440](https://github.com/biomejs/biome/pull/11440) [`b88f1ea`](https://github.com/biomejs/biome/commit/b88f1ea368c727ff8ebeddcaf9448f6ddc7c4878) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed HTML comments inside an Astro expression failing to parse. They are now read as trivia, wherever they appear among the children. ```astro {x && <div><!-- first -->text<!-- last --></div>} {cond && <a></a><!-- c --><b></b>} ``` - [#&#8203;11440](https://github.com/biomejs/biome/pull/11440) [`b88f1ea`](https://github.com/biomejs/biome/commit/b88f1ea368c727ff8ebeddcaf9448f6ddc7c4878) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed `is:raw` children inside an Astro expression being read as JSX, such as `{x && <div is:raw>{not js} < & text</div>}`. - [#&#8203;11440](https://github.com/biomejs/biome/pull/11440) [`b88f1ea`](https://github.com/biomejs/biome/commit/b88f1ea368c727ff8ebeddcaf9448f6ddc7c4878) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - 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>)}`. - [#&#8203;11440](https://github.com/biomejs/biome/pull/11440) [`b88f1ea`](https://github.com/biomejs/biome/commit/b88f1ea368c727ff8ebeddcaf9448f6ddc7c4878) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - 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. ```astro {cond && <style>a { color: red }</style>} {cond && <script>let x = {a: 1};</script>} ``` - [#&#8203;11440](https://github.com/biomejs/biome/pull/11440) [`b88f1ea`](https://github.com/biomejs/biome/commit/b88f1ea368c727ff8ebeddcaf9448f6ddc7c4878) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Added support for template literal attribute values inside an Astro expression, such as ``{x && <C data-x=`t${x}` />}``. - [#&#8203;11440](https://github.com/biomejs/biome/pull/11440) [`b88f1ea`](https://github.com/biomejs/biome/commit/b88f1ea368c727ff8ebeddcaf9448f6ddc7c4878) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed unquoted attribute values being rejected inside an Astro expression, such as `{x && <a class=foo maxlength=255 href=/about>go</a>}`. - [#&#8203;11440](https://github.com/biomejs/biome/pull/11440) [`b88f1ea`](https://github.com/biomejs/biome/commit/b88f1ea368c727ff8ebeddcaf9448f6ddc7c4878) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed a template literal nested inside `${}` breaking the rest of an Astro file, such as ``const href = `/blog${page === 0 ? '' : `/${page + 1}`}`;``. - [#&#8203;11440](https://github.com/biomejs/biome/pull/11440) [`b88f1ea`](https://github.com/biomejs/biome/commit/b88f1ea368c727ff8ebeddcaf9448f6ddc7c4878) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed a quote inside a regex character class breaking the rest of an Astro file, such as `const unsafe = /[/"]/;`. - [#&#8203;11508](https://github.com/biomejs/biome/pull/11508) [`54f3a2e`](https://github.com/biomejs/biome/commit/54f3a2ea2765c80df11d04e47cd8da0354f5f7ca) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`useFlatMathMinMax`](https://biomejs.dev/linter/rules/use-flat-math-min-max/). Because `Math.min()` and `Math.max()` accept any number of arguments, the rule reports unnecessary nested calls to the same method: ```js Math.max(Math.max(a, b), c); ``` The fix flattens this expression to `Math.max(a, b, c)`. - [#&#8203;11585](https://github.com/biomejs/biome/pull/11585) [`c5c8315`](https://github.com/biomejs/biome/commit/c5c8315cc2174b52834513d4c01edd09341e46cd) Thanks [@&#8203;Netail](https://github.com/Netail)! - Fixed [#&#8203;11475](https://github.com/biomejs/biome/issues/11475): `noUnresolvedImports` no longer reports Bun runtime built-in modules (`bun`, `bun:bundle`, `bun:ffi`, `bun:jsc`, `bun:sqlite`, `bun:test`). - [#&#8203;11368](https://github.com/biomejs/biome/pull/11368) [`52a57b3`](https://github.com/biomejs/biome/commit/52a57b374af947ffcba11f0dd97b3cb9676ce044) Thanks [@&#8203;Austin1serb](https://github.com/Austin1serb)! - Fixed [#&#8203;6830](https://github.com/biomejs/biome/issues/6830): Biome now reports a diagnostic for excessively deep syntax instead of overflowing the native stack while releasing the parsed tree. - [#&#8203;11596](https://github.com/biomejs/biome/pull/11596) [`1fc42ed`](https://github.com/biomejs/biome/commit/1fc42ed80a00e3ca86d44de8e1f66707061eb862) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`noThisOutsideOfClass`](https://biomejs.dev/linter/rules/no-this-outside-of-class/). The rule reports `this` outside class members and TypeScript functions with an explicit `this` parameter. ```js function Person(name) { this.name = name; } ``` - [#&#8203;11555](https://github.com/biomejs/biome/pull/11555) [`2516335`](https://github.com/biomejs/biome/commit/25163350c44aee821d3aeac5b20569cd37d1ae31) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11529](https://github.com/biomejs/biome/issues/11529), where [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/) 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. - [#&#8203;11518](https://github.com/biomejs/biome/pull/11518) [`0fee70c`](https://github.com/biomejs/biome/commit/0fee70c6420140d62e9e9507ff3eda735077691b) Thanks [@&#8203;HarperZ9](https://github.com/HarperZ9)! - Fixed [#&#8203;11500](https://github.com/biomejs/biome/issues/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. - [#&#8203;11580](https://github.com/biomejs/biome/pull/11580) [`1277af2`](https://github.com/biomejs/biome/commit/1277af285ff5ab2e7a4deb07b32855c9caa7b770) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;5091](https://github.com/biomejs/biome/issues/5091): Biome no longer moves comments next to the `<` of a generic, which causes invalid TypeScript syntax: ```diff - Generic<// a comment + Generic< + // a comment ``` - [#&#8203;11577](https://github.com/biomejs/biome/pull/11577) [`42995d2`](https://github.com/biomejs/biome/commit/42995d2d19a937c44e9abbd400901bc6ec0dcaf5) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;4592](https://github.com/biomejs/biome/issues/4592). Biome no longer crashes while parsing malformed `delete` expressions. - [#&#8203;11590](https://github.com/biomejs/biome/pull/11590) [`67963b4`](https://github.com/biomejs/biome/commit/67963b4085558e414bc48bddb82618b7cc6d8fdf) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;6427](https://github.com/biomejs/biome/issues/6427) so Grit plugins can use `function = ...` as a node argument. - [#&#8203;11600](https://github.com/biomejs/biome/pull/11600) [`a689cb5`](https://github.com/biomejs/biome/commit/a689cb5405885db94693e8ce39a22a53950cf2bf) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;6644](https://github.com/biomejs/biome/issues/6644): [`noUnusedVariables`](https://biomejs.dev/linter/rules/no-unused-variables/) now recognizes all interface declarations in a TypeScript declaration-merging group when the interface is referenced. The following snippet no longer triggers the rule. ```ts interface Things { foo: string; } interface Things { bar: string; } export type Key = keyof Things; interface Things { baz: string; } ``` - [#&#8203;11591](https://github.com/biomejs/biome/pull/11591) [`d4a0716`](https://github.com/biomejs/biome/commit/d4a07167df43309f424dc906fc5d0dc80b5e208d) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;6615](https://github.com/biomejs/biome/issues/6615). [`noDuplicateProperties`](https://biomejs.dev/linter/rules/no-duplicate-properties/) no longer reports declarations nested in block at-rules as duplicates of declarations in their parent block. - [#&#8203;11492](https://github.com/biomejs/biome/pull/11492) [`f2a07aa`](https://github.com/biomejs/biome/commit/f2a07aadedd47034dccffd941935c71481b4c354) Thanks [@&#8203;santichausis](https://github.com/santichausis)! - Fixed [#&#8203;11454](https://github.com/biomejs/biome/issues/11454): [`noMisplacedAssertion`](https://biomejs.dev/linter/rules/no-misplaced-assertion/) now recognises `@fast-check/vitest`'s `test.prop(...)` (and `.concurrent.prop`, `.skip.prop`, etc.) as a test function, the same way it already recognises `test.each`. The JS formatter picks up the same recognition, so a curried `test.prop(...)(...)` call is now formatted with the regular breakable argument layout used for `test.each`/`test.for`, instead of the single-line-hugging layout used for plain `it`/`test` calls. For example, Biome no longer reports the assertion below as misplaced: ```js import { fc, test } from "@fast-check/vitest"; test.prop([fc.string()])("round-trips", (s) => { expect(s).toBe(s); }); ``` - [#&#8203;11589](https://github.com/biomejs/biome/pull/11589) [`65742b3`](https://github.com/biomejs/biome/commit/65742b3658ab08aed31be6afdfbb4d8d5a737c47) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;4928](https://github.com/biomejs/biome/issues/4928): [`noUnusedVariables`](https://biomejs.dev/linter/rules/no-unused-variables/) no longer reports a value declaration as unused when its merged namespace is referenced. - [#&#8203;11559](https://github.com/biomejs/biome/pull/11559) [`472dbc2`](https://github.com/biomejs/biome/commit/472dbc2c38ed1dbed6066fe26eac7ef97c79b05d) Thanks [@&#8203;levrik](https://github.com/levrik)! - Fixed a false positive in [`noVueDuplicateKeys`](https://biomejs.dev/linter/rules/no-vue-duplicate-keys/) where a `<script setup>` variable initialized from `props` was reported as a duplicate of the prop it derives from. Biome now exempts any variable whose initializer references `props`, instead of only recognizing `defineProps()` and `toRefs(props)`. For example, Biome no longer reports `foo` below as a duplicate key: ```vue <script setup> import { toRef } from 'vue'; const props = defineProps(['foo']); const foo = toRef(props, 'foo'); </script> ``` - [#&#8203;11594](https://github.com/biomejs/biome/pull/11594) [`6586ceb`](https://github.com/biomejs/biome/commit/6586cebec6182d37361ce42ca906ab190fd9a15b) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;6640](https://github.com/biomejs/biome/issues/6640). Biome no longer crashes when linting malformed `for...of` statements. - [#&#8203;11571](https://github.com/biomejs/biome/pull/11571) [`85b197d`](https://github.com/biomejs/biome/commit/85b197da722fc8d07cd10b8fa7e1271652ed5e26) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;10838](https://github.com/biomejs/biome/issues/10838): [`useSortedAttributes`](https://biomejs.dev/assist/actions/use-sorted-attributes/) no longer corrupts JSX attributes when nested JSX elements also require sorting. - [#&#8203;11533](https://github.com/biomejs/biome/pull/11533) [`97e76c0`](https://github.com/biomejs/biome/commit/97e76c04cf19de45e63a22a9954c5077f45d4e6c) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;11520](https://github.com/biomejs/biome/issues/11520), where the Biome scanner would start analysing dependencies multiple times, leading to long and unresponsive sessions. - [#&#8203;11564](https://github.com/biomejs/biome/pull/11564) [`18a0e1f`](https://github.com/biomejs/biome/commit/18a0e1f058df3c8434d98d700eef5949695cb8f6) Thanks [@&#8203;Netail](https://github.com/Netail)! - Fixed the diagnostic range of [`noInferrableTypes`](https://biomejs.dev/linter/rules/no-inferrable-types/) so it now highlights only the type instead of including the leading `:` colon, spaces and comments. - [#&#8203;11540](https://github.com/biomejs/biome/pull/11540) [`124fdaa`](https://github.com/biomejs/biome/commit/124fdaa1dad40a1e5d485da13ca51064b0a40adb) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [`#11537`](https://github.com/biomejs/biome/issues/11537): [`noShorthandPropertyOverrides`](https://biomejs.dev/linter/rules/no-shorthand-property-overrides/) now compares declarations only within the same block. The rule no longer reports `@supports` feature queries and correctly checks nested, `@keyframes`, and `@page` blocks. - [#&#8203;11532](https://github.com/biomejs/biome/pull/11532) [`7ceb0ee`](https://github.com/biomejs/biome/commit/7ceb0ee925461abd9afe17b12a09abc9c0b43c28) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11528](https://github.com/biomejs/biome/issues/11528): [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/) no longer reports statement-level `await` expressions that handle Promise values, including overloaded calls returning Promise aliases. Awaited values that resolve to arrays of Promises remain reported because their element Promises are not handled by `await`. - [#&#8203;11474](https://github.com/biomejs/biome/pull/11474) [`3c6412e`](https://github.com/biomejs/biome/commit/3c6412e7f44b9aaac750844f9a5f7ff7c3aa0feb) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10241](https://github.com/biomejs/biome/issues/10241). Biome no longer reports unsupported text expression diagnostics for double-curly text in vanilla HTML, and the formatter preserves adjacent curly-brace text. - [#&#8203;11593](https://github.com/biomejs/biome/pull/11593) [`6c7fd27`](https://github.com/biomejs/biome/commit/6c7fd273848765547dba547e550fc319df7455a0) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`noVueDeprecatedScopedSlots`](https://biomejs.dev/linter/rules/no-vue-deprecated-scoped-slots/). It reports deprecated `$scopedSlots` references in Vue templates and component objects, and offers an unsafe replacement with `$slots`. For example, Biome now reports `this.$scopedSlots.default` inside a Vue component. - [#&#8203;11440](https://github.com/biomejs/biome/pull/11440) [`b88f1ea`](https://github.com/biomejs/biome/commit/b88f1ea368c727ff8ebeddcaf9448f6ddc7c4878) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed the formatter crashing on an Astro or Svelte expression spanning several lines in a file with CRLF line endings, such as `<p>{a +\r\n b}</p>`. - [#&#8203;11581](https://github.com/biomejs/biome/pull/11581) [`f4e5ebb`](https://github.com/biomejs/biome/commit/f4e5ebb40e64d4488166bf0f2b7d8d96a6118016) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`useModernMathApis`](https://biomejs.dev/linter/rules/use-modern-math-apis/). The rule reports legacy mathematical patterns that have direct modern `Math` equivalents. ```js Math.sqrt(a * a + b * b); ``` - [#&#8203;11597](https://github.com/biomejs/biome/pull/11597) [`a20f44a`](https://github.com/biomejs/biome/commit/a20f44a3eb2086e65a6d8077eb89ab81f4d73130) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the nursery rule [`noBunModules`](https://biomejs.dev/linter/rules/no-bun-modules/), which forbids the use of Bun builtin modules (e.g. `bun:sqlite`, `bun:ffi`). - [#&#8203;11545](https://github.com/biomejs/biome/pull/11545) [`7d54688`](https://github.com/biomejs/biome/commit/7d54688ee89244af3b287402295340d1d35ca96e) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11542](https://github.com/biomejs/biome/issues/11542): Biome now reports HTML comments between Svelte tag attributes as parse errors. - [#&#8203;11582](https://github.com/biomejs/biome/pull/11582) [`b6611dd`](https://github.com/biomejs/biome/commit/b6611dd5c1a54b80f181f4c0b5147a2c1c311dc9) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;3862](https://github.com/biomejs/biome/issues/3862). Biome now parses legacy Internet Explorer `filter` and `-ms-filter` values such as `progid:DXImageTransform...` and `alpha(opacity=40)`. - [#&#8203;11575](https://github.com/biomejs/biome/pull/11575) [`65da251`](https://github.com/biomejs/biome/commit/65da251b0f4da0680f7ccb8820ba428344018848) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Improved the Tailwind parser's ability to recover from parsing failures. Whitespace now always allows the parser to recover and start parsing a new class. - [#&#8203;11576](https://github.com/biomejs/biome/pull/11576) [`0f78499`](https://github.com/biomejs/biome/commit/0f784998407970338481a1017279b9f17c43c61f) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;3515](https://github.com/biomejs/biome/issues/3515) and [#&#8203;10395](https://github.com/biomejs/biome/issues/10395), where Biome could corrupt Unicode characters while writing source received through standard input to standard output. Characters such as `⚠` and `✔` are now preserved. - [#&#8203;11539](https://github.com/biomejs/biome/pull/11539) [`0fca643`](https://github.com/biomejs/biome/commit/0fca643d22845c28e0e0b7375013155e3f80717f) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;11512](https://github.com/biomejs/biome/issues/11512), where [`style/noDescendingSpecificity`](https://biomejs.dev/linter/rules/no-descending-specificity/) missed lower-specificity selectors after a later higher-specificity selector with the same tail selector. - [#&#8203;11544](https://github.com/biomejs/biome/pull/11544) [`040f867`](https://github.com/biomejs/biome/commit/040f86770cb830cd9ddaa827fd5b78fa16e7484c) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11541](https://github.com/biomejs/biome/issues/11541): formatting a Svelte render tag followed by an HTML comment no longer duplicates the comment. ```diff <div> {@render children?.()} <!-- comment --> - <!-- comment --> </div> ``` - [#&#8203;11565](https://github.com/biomejs/biome/pull/11565) [`ee69e0e`](https://github.com/biomejs/biome/commit/ee69e0e8a90e6231a3b208cda4b3e65ad8b2006a) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;11525](https://github.com/biomejs/biome/issues/11525). Now the configuration schema correctly provides auto-completion for linter domains. - [#&#8203;11583](https://github.com/biomejs/biome/pull/11583) [`b19390c`](https://github.com/biomejs/biome/commit/b19390cb6ec276651365542387469c8b4634e0af) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11352](https://github.com/biomejs/biome/issues/11352): [`useExplicitLengthCheck`](https://biomejs.dev/linter/rules/use-explicit-length-check/) no longer reports `length`-like properties used as value-producing `||` fallbacks or optional chains, and it no longer offers fixes for value-producing `&&` checks or unsafe negations. - [#&#8203;11562](https://github.com/biomejs/biome/pull/11562) [`753e955`](https://github.com/biomejs/biome/commit/753e955afe7bcb360506795fed25697828a59772) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed an issue where the Biome Language Server would start with logging level set to debug. This would cause logs to grow exponentially in long sessions. - [#&#8203;11217](https://github.com/biomejs/biome/pull/11217) [`7d3ee9c`](https://github.com/biomejs/biome/commit/7d3ee9ccd5cf5df585ab3a17517a9514608a645a) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed handling of `biome-ignore format` suppression comments on TypeScript declared class properties with string literal names. ```ts class A { declare /* biome-ignore format: exercise suppression checking */ 'a-b': 0; } ``` - [#&#8203;11497](https://github.com/biomejs/biome/pull/11497) [`f5d7896`](https://github.com/biomejs/biome/commit/f5d7896f7115a2d57962471f6d7abfafddb07918) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the [`noInvalidFileInputAccept`](https://biomejs.dev/linter/rules/no-invalid-file-input-accept/) nursery rule. The rule reports invalid literal `accept` values on file inputs in JSX and HTML, and normalizes common mistakes. ```jsx <input type="file" accept="image/jpg" /> ``` - [#&#8203;11345](https://github.com/biomejs/biome/pull/11345) [`ac58958`](https://github.com/biomejs/biome/commit/ac58958135d79e790f0edee8ec18aaa16f5d9849) Thanks [@&#8203;jakeleventhal](https://github.com/jakeleventhal)! - Improved type inference performance by avoiding resolution of unused members in object arguments. - [#&#8203;11554](https://github.com/biomejs/biome/pull/11554) [`2d55931`](https://github.com/biomejs/biome/commit/2d559316e00764b0843d3d483d4a093fb566de57) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the new nursery rule [`useReactNamingConvention`](https://biomejs.dev/linter/rules/use-react-naming-convention/), which enforces naming conventions for React values assigned from `createContext`, `useId`, and `useRef`. A value from `createContext` must be a PascalCase component name ending with `Context`, a value from `useId` must be named `id` or end with `Id`, and a value from `useRef` must be named `ref` or end with `Ref`. - [#&#8203;11491](https://github.com/biomejs/biome/pull/11491) [`1d6210b`](https://github.com/biomejs/biome/commit/1d6210b8ef6a2d2d83ea16e6fb95c124fd370690) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`noUnmodifiedLoopCondition`](https://biomejs.dev/linter/rules/no-unmodified-loop-condition/), which reports variables in loop conditions that are never modified in the loop. ```js let node = getNode(); while (node) { process(node); } ``` ### [`v2.5.11`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#2511) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.10...@biomejs/biome@2.5.11) ##### Patch Changes - [#&#8203;11499](https://github.com/biomejs/biome/pull/11499) [`9743d0c`](https://github.com/biomejs/biome/commit/9743d0ceae807757300e5b0ec66266125bc664c1) Thanks [@&#8203;scs0209](https://github.com/scs0209)! - Fixed [#&#8203;11496](https://github.com/biomejs/biome/issues/11496): [`useValidAnchor`](https://biomejs.dev/linter/rules/use-valid-anchor/) now treats Astro JSX shorthand attributes like `<a {href}>` as a valid `href`. - [#&#8203;11437](https://github.com/biomejs/biome/pull/11437) [`88f805e`](https://github.com/biomejs/biome/commit/88f805e19b67ab4c876e4fc4a8b4018bd03df20b) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed [#&#8203;9944](https://github.com/biomejs/biome/issues/9944): adjacent elements inside an Astro expression now parse as an implicit fragment instead of raising an error. ```astro {options.map(() => <div /> <div /> )} ``` - [#&#8203;11437](https://github.com/biomejs/biome/pull/11437) [`88f805e`](https://github.com/biomejs/biome/commit/88f805e19b67ab4c876e4fc4a8b4018bd03df20b) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed Astro templates rejecting unclosed HTML void elements, such as `{cond && <br>}`. - [#&#8203;11507](https://github.com/biomejs/biome/pull/11507) [`e2fc036`](https://github.com/biomejs/biome/commit/e2fc03669886732ac9c768aa00f3ffae46241848) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11157](https://github.com/biomejs/biome/issues/11157): [`noUnusedVariables`](https://biomejs.dev/linter/rules/no-unused-variables/) no longer reports Vue `<script setup>` bindings used by CSS `v-bind()` as unused. - [#&#8203;11398](https://github.com/biomejs/biome/pull/11398) [`afc4615`](https://github.com/biomejs/biome/commit/afc4615079a72e0810f06186f78e5cb177a5638e) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11389](https://github.com/biomejs/biome/issues/11389): Files passed through `--stdin-file-path` now use full HTML support for Astro, Svelte, and Vue when it is enabled. - [#&#8203;11526](https://github.com/biomejs/biome/pull/11526) [`372cd68`](https://github.com/biomejs/biome/commit/372cd68ba156efdc497017598a49e21484a3ada9) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [`noVueRefAsOperand`](https://biomejs.dev/linter/rules/no-vue-ref-as-operand/) 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. - [#&#8203;11458](https://github.com/biomejs/biome/pull/11458) [`a7cd286`](https://github.com/biomejs/biome/commit/a7cd2868c3d98fbc75174c5bf69fdcfacbe87304) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11436](https://github.com/biomejs/biome/issues/11436): GritQL snippets such as `export { $specifiers } from $source` now match named re-exports with aliases, inline `type` modifiers, and multiple specifiers. - [#&#8203;11515](https://github.com/biomejs/biome/pull/11515) [`382b15d`](https://github.com/biomejs/biome/commit/382b15d5e0f9e2a75604fec1f15ad342628c99c7) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11390](https://github.com/biomejs/biome/issues/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. - [#&#8203;11516](https://github.com/biomejs/biome/pull/11516) [`6f40e82`](https://github.com/biomejs/biome/commit/6f40e8224afc58737626d997c0ea779e2b37baca) Thanks [@&#8203;levrik](https://github.com/levrik)! - Fixed [`noVueRefAsOperand`](https://biomejs.dev/linter/rules/no-vue-ref-as-operand/) 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. ```js 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. - [#&#8203;11495](https://github.com/biomejs/biome/pull/11495) [`496268d`](https://github.com/biomejs/biome/commit/496268d1470b6a4cd52bff03d37899c4bb7f77ab) Thanks [@&#8203;Netail](https://github.com/Netail)! - Fixed [`useGraphqlNamingConvention`](https://biomejs.dev/linter/rules/use-graphql-naming-convention/) so it no longer reports GraphQL enum value definitions with comments & descriptions and now displays a more accurate diagnostic range. - [#&#8203;11407](https://github.com/biomejs/biome/pull/11407) [`6ef52b0`](https://github.com/biomejs/biome/commit/6ef52b02fc07e23de7ad498d853aaf2c825717fd) Thanks [@&#8203;1678092075](https://github.com/1678092075)! - Fixed [#&#8203;11214](https://github.com/biomejs/biome/issues/11214): [`noUnusedVariables`](https://biomejs.dev/linter/rules/no-unused-variables/) no longer reports type parameters declared by non-default function overload signatures that have an implementation. - [#&#8203;11322](https://github.com/biomejs/biome/pull/11322) [`5c353e6`](https://github.com/biomejs/biome/commit/5c353e6c85a40807e2710684da807f8757ee650c) Thanks [@&#8203;jp-knj](https://github.com/jp-knj)! - 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: ```astro <div set:html={content} /> ``` - [#&#8203;11462](https://github.com/biomejs/biome/pull/11462) [`18883b7`](https://github.com/biomejs/biome/commit/18883b7dafb8f9581534508fdd5b1e34632f2724) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10776](https://github.com/biomejs/biome/issues/10776): [`useVueHyphenatedAttributes`](https://biomejs.dev/linter/rules/use-vue-hyphenated-attributes/) no longer reports lowercase attribute names containing punctuation, such as `pt:header:data-test-id` and `some_attr`. - [#&#8203;11476](https://github.com/biomejs/biome/pull/11476) [`3270ca4`](https://github.com/biomejs/biome/commit/3270ca4560a28eee92564b9ef64f778972cbf3ab) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10330](https://github.com/biomejs/biome/issues/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. ```diff -<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> ``` - [#&#8203;11191](https://github.com/biomejs/biome/pull/11191) [`3e5367f`](https://github.com/biomejs/biome/commit/3e5367f13de6c8cb80070544774c9935cac7d649) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Added the nursery rule [`noUndeclaredCustomProperties`](https://biomejs.dev/linter/rules/no-undeclared-custom-properties/), 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: ```css a { color: var(--undefined-color); } ``` - [#&#8203;11435](https://github.com/biomejs/biome/pull/11435) [`7754894`](https://github.com/biomejs/biome/commit/7754894ffaaaa2ab0b281789d5ceae8f333d61a4) Thanks [@&#8203;levrik](https://github.com/levrik)! - Fixed: Variables and imports used as custom Vue directives are no longer reported as unused. For example: ```vue <script setup> const vHighlight = { mounted: (element) => { element.style.color = "red"; }, }; </script> <template> <p v-highlight>Hello</p> </template> ``` - [#&#8203;11501](https://github.com/biomejs/biome/pull/11501) [`e6acded`](https://github.com/biomejs/biome/commit/e6acdedf09c452371670aaaffd0b55206019d1e6) Thanks [@&#8203;aminya](https://github.com/aminya)! - Improved the performance of [`useArraySortCompare`](https://biomejs.dev/linter/rules/use-array-sort-compare/) by skipping type inference for calls to unrelated methods. - [#&#8203;11467](https://github.com/biomejs/biome/pull/11467) [`66b282c`](https://github.com/biomejs/biome/commit/66b282cb70cd61b7606ce1658482b9fe082e37e6) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11464](https://github.com/biomejs/biome/issues/11464): Biome now parses parenthesized object literals returned from arrow functions when they contain a conditional expression and a nested arrow function. - [#&#8203;11456](https://github.com/biomejs/biome/pull/11456) [`db9aa2a`](https://github.com/biomejs/biome/commit/db9aa2a3d936372cbe3ee87687ad25816c9d75ae) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10278](https://github.com/biomejs/biome/issues/10278): Marked the fix for [`noThisInStatic`](https://biomejs.dev/linter/rules/no-this-in-static/) as unsafe by default. - [#&#8203;11502](https://github.com/biomejs/biome/pull/11502) [`652aedb`](https://github.com/biomejs/biome/commit/652aedbdcba8ccb45ccecbce506c90a337f2d64c) Thanks [@&#8203;levrik](https://github.com/levrik)! - `noGlobalAssign` no longer reports assignments to a Vue `<script setup>` binding from a template expression, when the binding's name happens to match a built-in global (e.g. `open`, `parent`, `top`). For example, this no longer triggers a diagnostic: ```vue <script setup> const open = defineModel(); </script> <template> <button @click="open = !open">Toggle</button> </template> ``` ### [`v2.5.10`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#2510) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.9...@biomejs/biome@2.5.10) ##### Patch Changes - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed Astro rejecting JavaScript comments between attributes. ```astro <div /* block comment */ class="something"></div> <Component /* c */ client:load /> ``` - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - 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. - [#&#8203;11438](https://github.com/biomejs/biome/pull/11438) [`3133ffa`](https://github.com/biomejs/biome/commit/3133ffa9ae6beaa3c4464edac60de47d5c6f6426) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed [#&#8203;8294](https://github.com/biomejs/biome/issues/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. ```astro <div>{/* a note */}</div> <div class={/* a note */}>x</div> ``` - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed [#&#8203;9165](https://github.com/biomejs/biome/issues/9165): an empty Astro expression such as `<div>{}</div>` no longer fails to parse. Astro renders `{}` as nothing. - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed Astro expressions containing a comment failing to parse. ```astro <div>{/* block comment */ x}</div> <div>{/* only a comment */}</div> ``` - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Added support for Astro's fragment shorthand. ```astro <> <p>a</p> </> ``` - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed an Astro frontmatter block being cut short by a closing tag inside a string or comment. ```astro --- const a = "</script>"; // </script> in a comment --- ``` - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - 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. ```astro <!-- c --> --- this is text, not frontmatter --- ``` - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed an Astro frontmatter block ending early on a line that merely starts with a dash. ```astro --- --count; --- ``` - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - 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. ```astro <article is:raw><% awesome %></article> <script is:raw>{{ mustache }}</script> ``` - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed Astro rejecting attribute names that start with a colon, such as `:href`. - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - 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. - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - 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. - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - 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. - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - 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. ```astro <pre>{value}</pre> <textarea><div>{value}</div></textarea> ``` - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Added support for template literal attribute values in Astro, such as ``<div class=`a ${b} c`>``. - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed Astro rejecting HTML5 unquoted attribute values that contain `` ` ``, `=`, `'` or `"`, such as `<a href=a=b>` and `<a href=a'b>`. - [#&#8203;11393](https://github.com/biomejs/biome/pull/11393) [`dec5a8f`](https://github.com/biomejs/biome/commit/dec5a8fadcb565867526e51da0895c2be27400bb) Thanks [@&#8203;1678092075](https://github.com/1678092075)! - Fixed [#&#8203;11207](https://github.com/biomejs/biome/issues/11207): [`useStrictMode`](https://biomejs.dev/linter/rules/use-strict-mode/) no longer reports Vue event handlers such as `@click="count++"`. - [#&#8203;11431](https://github.com/biomejs/biome/pull/11431) [`c065f99`](https://github.com/biomejs/biome/commit/c065f995909d16cbf98c247a280a48c156aeb61f) Thanks [@&#8203;levrik](https://github.com/levrik)! - Fixed [#&#8203;11429](https://github.com/biomejs/biome/issues/11429): Variables and imports used by Vue same-name bindings such as `:disabled` or `v-bind:disabled` are no longer reported as unused. - [#&#8203;11409](https://github.com/biomejs/biome/pull/11409) [`405dedb`](https://github.com/biomejs/biome/commit/405dedb0ff65dd29927faf587f6542e3c29db248) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed a memory leak in the LSP server where memory usage kept growing over long editor sessions. - [#&#8203;11422](https://github.com/biomejs/biome/pull/11422) [`a51eff7`](https://github.com/biomejs/biome/commit/a51eff7f7ca71e8786a2f0db1d560455b83ce21c) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11416](https://github.com/biomejs/biome/issues/11416): Biome no longer crashes when parsing incomplete `{let}` or `{const}` declarations in Svelte files. - [#&#8203;11378](https://github.com/biomejs/biome/pull/11378) [`34b715c`](https://github.com/biomejs/biome/commit/34b715cb417d482bfb4630c05a576b748c8faa8b) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added extra rule sources from `@eslint/css`. `biome migrate eslint` detects rules in your eslint configurations more reliably. - [#&#8203;11403](https://github.com/biomejs/biome/pull/11403) [`8f7786f`](https://github.com/biomejs/biome/commit/8f7786ff62aef61cf75a91e1604cd380456a60f4) Thanks [@&#8203;Princesseuh](https://github.com/Princesseuh)! - Fixed `{#`, `{/`, `{:` and `{@` being read as Svelte block openings in every HTML-like file. They are now Svelte-only, so in HTML, Vue and Angular files a sequence such as `{#if x}` is ordinary text instead of a parse error. - [#&#8203;11443](https://github.com/biomejs/biome/pull/11443) [`8d45229`](https://github.com/biomejs/biome/commit/8d452293d04272c876b0414292540645cfea87e4) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;11390](https://github.com/biomejs/biome/issues/11390): [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/) no longer performs unnecessary type inference on call arguments when checking methods of non-generic class instances created with `new`. - [#&#8203;11425](https://github.com/biomejs/biome/pull/11425) [`9c2667b`](https://github.com/biomejs/biome/commit/9c2667ba2010441054bc0b54a1a810e851207560) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;6426](https://github.com/biomejs/biome/issues/6426): GritQL plugins now match and rewrite metavariables embedded in quoted strings. - [#&#8203;11441](https://github.com/biomejs/biome/pull/11441) [`00317c3`](https://github.com/biomejs/biome/commit/00317c353a65214d8f4cb0f2d930d7c4e1f305dd) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Improved performance of [`useNamedCaptureGroup`](https://biomejs.dev/linter/rules/use-named-capture-group/), [`noMisplacedAssertion`](https://biomejs.dev/linter/rules/no-misplaced-assertion/), [`noSkippedTests`](https://biomejs.dev/linter/rules/no-skipped-tests/), [`noExportsInTest`](https://biomejs.dev/linter/rules/no-exports-in-test/), [`noDuplicateTestHooks`](https://biomejs.dev/linter/rules/no-duplicate-test-hooks/), [`noIdenticalTestTitle`](https://biomejs.dev/linter/rules/no-identical-test-title/), [`useTestHooksInOrder`](https://biomejs.dev/linter/rules/use-test-hooks-in-order/), and [`useTestHooksOnTop`](https://biomejs.dev/linter/rules/use-test-hooks-on-top/). ### [`v2.5.9`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#259) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.8...@biomejs/biome@2.5.9) ##### Patch Changes - [#&#8203;11321](https://github.com/biomejs/biome/pull/11321) [`41386f3`](https://github.com/biomejs/biome/commit/41386f38935b299f1a1f759a2c7fdd5c2050bded) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11315](https://github.com/biomejs/biome/issues/11315): The CSS parser now recovers at declaration boundaries after bogus declarations, allowing subsequent valid declarations to be parsed. - [#&#8203;11248](https://github.com/biomejs/biome/pull/11248) [`57b197e`](https://github.com/biomejs/biome/commit/57b197e6d5a2432ff6904afff24125e4d8ec01cd) Thanks [@&#8203;yanthomasdev](https://github.com/yanthomasdev)! - 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. - [#&#8203;11377](https://github.com/biomejs/biome/pull/11377) [`a8798ea`](https://github.com/biomejs/biome/commit/a8798ea9f2569fab4524704c99a8e2fe45c2ca32) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added a new nursery rule [`useNamedLayer`](https://biomejs.dev/linter/rules/use-named-layer) which disallows anonymous cascade layers. ```css @layer { a { color: red; } } ``` - [#&#8203;11327](https://github.com/biomejs/biome/pull/11327) [`6771cf5`](https://github.com/biomejs/biome/commit/6771cf5bd2e64f256468a33b811adec8e793d933) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - The HTML formatter now preserves meaningful blank lines in HTML, including spacing after elements with trailing spaces and blank lines between comment groups. ```diff <div> <!-- first group --> + <!-- second group --> </div> ``` - [#&#8203;10312](https://github.com/biomejs/biome/pull/10312) [`ba8aa18`](https://github.com/biomejs/biome/commit/ba8aa183371b3080691ed80e5a9f6f0239cf451b) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`useTailwindShorthandClasses`](https://biomejs.dev/linter/rules/use-tailwind-shorthand-classes/), which suggests shorter Tailwind utility classes. For example, the rule suggests replacing `w-4 h-4` with `size-4`. - [#&#8203;11333](https://github.com/biomejs/biome/pull/11333) [`715e0cd`](https://github.com/biomejs/biome/commit/715e0cd1b3e6c88d153554901a659378c728e408) Thanks [@&#8203;kkkhs](https://github.com/kkkhs)! - Fixed [#&#8203;11328](https://github.com/biomejs/biome/issues/11328): `lint/nursery/useExpect` now recognizes Vitest Browser Mode `expect.element()` calls as assertions. - [#&#8203;11343](https://github.com/biomejs/biome/pull/11343) [`9b98211`](https://github.com/biomejs/biome/commit/9b982113dba8b37c163662d59611ecba0fc02f5a) Thanks [@&#8203;johncarmack1984](https://github.com/johncarmack1984)! - Fixed [#&#8203;11311](https://github.com/biomejs/biome/issues/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`](https://biomejs.dev/linter/rules/no-unknown-at-rules/) diagnostic. ```css @variant @xl { div { background: red; } } ``` - [#&#8203;11220](https://github.com/biomejs/biome/pull/11220) [`3e8c488`](https://github.com/biomejs/biome/commit/3e8c4887c4ef87df45f56aafa4fbc5f497dae42f) Thanks [@&#8203;santichausis](https://github.com/santichausis)! - Fixed [#&#8203;9541](https://github.com/biomejs/biome/issues/9541): [`noUndeclaredVariables`](https://biomejs.dev/linter/rules/no-undeclared-variables/), [`noUnusedImports`](https://biomejs.dev/linter/rules/no-unused-imports/), and [`noUnusedVariables`](https://biomejs.dev/linter/rules/no-unused-variables/) 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: ```svelte <script module> export function greet() { console.log("Hello!"); } </script> <script> greet(); </script> ``` - [#&#8203;11300](https://github.com/biomejs/biome/pull/11300) [`36430eb`](https://github.com/biomejs/biome/commit/36430ebb9679d1ca5d9c231a36b709a4b5eab9b3) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed the HTML formatter's whitespace handling for `marquee`, `noscript`, `video`, `audio`, and `object` elements. ```diff - <marquee behavior="alternate"> This text will bounce </marquee> + <marquee behavior="alternate">This text will bounce</marquee> ``` - [#&#8203;11299](https://github.com/biomejs/biome/pull/11299) [`6559e6c`](https://github.com/biomejs/biome/commit/6559e6ced6d4ebe8c26e818931df15d02829130d) Thanks [@&#8203;jp-knj](https://github.com/jp-knj)! - Added the nursery rule `useAstroClientOnlyDirectiveValue`, which reports Astro `client:only` directives without an initializer. For example, `<Component client:only />` triggers the rule. - [#&#8203;11365](https://github.com/biomejs/biome/pull/11365) [`7529811`](https://github.com/biomejs/biome/commit/7529811358079edb5a2a9d4a5f67a9f639a63f3a) Thanks [@&#8203;MHJahanbakhsh](https://github.com/MHJahanbakhsh)! - Fixed [#&#8203;11229](https://github.com/biomejs/biome/issues/11229): The [`useGenericFontNames`](https://biomejs.dev/linter/rules/use-generic-font-names/) rule now treats `math` as a valid generic font family. - [#&#8203;11346](https://github.com/biomejs/biome/pull/11346) [`674f5f4`](https://github.com/biomejs/biome/commit/674f5f4b4e6923b6c7fd12d76e366f82ffe6405b) Thanks [@&#8203;Jayllyz](https://github.com/Jayllyz)! - Fixed [#&#8203;11335](https://github.com/biomejs/biome/issues/11335): [`noComponentHookFactories`](https://biomejs.dev/linter/rules/no-component-hook-factories/) now reports a `use`-prefixed variable only when a function is assigned to it directly. ```js function factory() { const useColors = true; // no longer reported const useStore = createStore({ count: 0 }); // no longer reported const useData = () => useState(null); // still reported return useColors; } ``` - [#&#8203;11334](https://github.com/biomejs/biome/pull/11334) [`c87c46a`](https://github.com/biomejs/biome/commit/c87c46ab350a40fd38b2288887e2d6e930a2d62d) Thanks [@&#8203;zkasuran](https://github.com/zkasuran)! - Fixed [#&#8203;11317](https://github.com/biomejs/biome/issues/11317): [`noSvgWithoutTitle`](https://biomejs.dev/linter/rules/no-svg-without-title/) no longer reports an `svg` that uses the boolean shorthand `aria-hidden` (equivalent to `aria-hidden={true}` in React). - [#&#8203;11364](https://github.com/biomejs/biome/pull/11364) [`13853b1`](https://github.com/biomejs/biome/commit/13853b16685d96bfb9158de7d5f4c101d114ba32) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed a bug where [`useJsxKeyInIterable`](https://biomejs.dev/linter/rules/use-jsx-key-in-iterable/) incorrectly flagged Astro files. - [#&#8203;11321](https://github.com/biomejs/biome/pull/11321) [`41386f3`](https://github.com/biomejs/biome/commit/41386f38935b299f1a1f759a2c7fdd5c2050bded) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11315](https://github.com/biomejs/biome/issues/11315): Invalid CSS declarations in HTML `style` attributes now produce parser diagnostics instead of causing a panic. - [#&#8203;11325](https://github.com/biomejs/biome/pull/11325) [`67c3bf0`](https://github.com/biomejs/biome/commit/67c3bf01131c0c079fa058eef96dc28d52c2c59f) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - 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. ```diff <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 > ``` - [#&#8203;11367](https://github.com/biomejs/biome/pull/11367) [`fe5b5d4`](https://github.com/biomejs/biome/commit/fe5b5d41c863d5e2f3b58570e15f483c189d2825) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed TypeScript `compilerOptions.paths` resolution when mapping targets omit `./`. Biome now resolves these targets relative to their configured path base. - [#&#8203;11316](https://github.com/biomejs/biome/pull/11316) [`17e48d6`](https://github.com/biomejs/biome/commit/17e48d6088f23ec30a1e17e315b52369f1e4836c) Thanks [@&#8203;wanxiankai](https://github.com/wanxiankai)! - Fixed [#&#8203;11289](https://github.com/biomejs/biome/issues/11289): the safe fix for [`noExtraBooleanCast`](https://biomejs.dev/linter/rules/no-extra-boolean-cast/) now preserves parentheses around nested conditional expressions. - [#&#8203;11254](https://github.com/biomejs/biome/pull/11254) [`d25d113`](https://github.com/biomejs/biome/commit/d25d113aed23ca9b5ee9b7cdedb208d8a0b2cd00) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11242](https://github.com/biomejs/biome/issues/11242): Biome no longer crashes with an access violation when analysing files on Windows ARM64. - [#&#8203;11221](https://github.com/biomejs/biome/pull/11221) [`85aac73`](https://github.com/biomejs/biome/commit/85aac73d32a5f4a0db7bab3ebd195e35b32d513d) Thanks [@&#8203;freeatnet](https://github.com/freeatnet)! - Added the nursery rule [`noUnsafeTypeAssertion`](https://biomejs.dev/linter/rules/no-unsafe-type-assertion/), which disallows TypeScript type assertions while allowing const assertions. ```ts const value = input as SomeType; ``` - [#&#8203;11314](https://github.com/biomejs/biome/pull/11314) [`7ffb677`](https://github.com/biomejs/biome/commit/7ffb677159c96f072a508e58bfad26ca9c301ac4) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;11310](https://github.com/biomejs/biome/issues/11310): Restored the performance of [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises/) and [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/) when analyzed expressions share deep imported type paths. - [#&#8203;11356](https://github.com/biomejs/biome/pull/11356) [`6cd3263`](https://github.com/biomejs/biome/commit/6cd32636f463551b8dfe46aeefb1191d437b4694) Thanks [@&#8203;johncarmack1984](https://github.com/johncarmack1984)! - The Tailwind parser now understands modifiers on bare utilities (`@container/sidebar`, `shadow/50`). - [#&#8203;11318](https://github.com/biomejs/biome/pull/11318) [`76059e9`](https://github.com/biomejs/biome/commit/76059e9f03f5962a18f3569714f8f207ef7c1d91) Thanks [@&#8203;johncarmack1984](https://github.com/johncarmack1984)! - The Tailwind parser now understands container-query variants (`@sm:`, `@max-lg:`, `@min-[400px]:`) and child and descendant variants (`*:`, `**:`). - [#&#8203;11357](https://github.com/biomejs/biome/pull/11357) [`faa2074`](https://github.com/biomejs/biome/commit/faa2074472bc0f4a11f4e80cb4d2b0e55883226a) Thanks [@&#8203;johncarmack1984](https://github.com/johncarmack1984)! - The Tailwind parser now accepts the legacy leading `!` important marker (`!flex`, `hover:!p-4`). - [#&#8203;11344](https://github.com/biomejs/biome/pull/11344) [`f34e15c`](https://github.com/biomejs/biome/commit/f34e15c946511d998c01b6c6e410f0c220c2943e) Thanks [@&#8203;johncarmack1984](https://github.com/johncarmack1984)! - The Tailwind parser now understands combinator selectors in arbitrary variants (`has-[>svg]:`, `has-[+p]:`), modifiers on variants (`group-hover/menu:`, `@sm/main:`), and arbitrary container-query sizes (`@[400px]:`). - [#&#8203;11324](https://github.com/biomejs/biome/pull/11324) [`2f5d452`](https://github.com/biomejs/biome/commit/2f5d452015ee80a02d4e50c4bb2ba930092048a2) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed HTML formatting that inserted rendered whitespace between an element and touching text when the line wrapped. ```diff <div> - before<meter value=".5"></meter> - after + before<meter value=".5"></meter + >after </div> ``` - [#&#8203;11312](https://github.com/biomejs/biome/pull/11312) [`e65f07e`](https://github.com/biomejs/biome/commit/e65f07e06342c7d8d74b98ff219d72c7e081b4f2) Thanks [@&#8203;xosnos](https://github.com/xosnos)! - Added a new nursery rule [`useControlLabel`](https://biomejs.dev/linter/rules/use-control-label/) for both HTML and JSX, which reports interactive control elements (`button`, `menuitem`) without an accessible label. ```jsx <button /> ``` - [#&#8203;11364](https://github.com/biomejs/biome/pull/11364) [`13853b1`](https://github.com/biomejs/biome/commit/13853b16685d96bfb9158de7d5f4c101d114ba32) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed SVG parsing for files with an XML declaration followed by a `PUBLIC` doctype, such as `<?xml version="1.0"?><!DOCTYPE svg PUBLIC "a" "b">`. - [#&#8203;11301](https://github.com/biomejs/biome/pull/11301) [`610ee28`](https://github.com/biomejs/biome/commit/610ee282989ac73908e0f8bd6e49bc40cccfef77) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed parent tag wrapping when an HTML element starts or ends with a block-like or hidden child such as `source`, `track`, or `param`. ```diff - <video src="brave.webm"><track kind="subtitles" src="brave.en.vtt"></video> + <video src="brave.webm"> + <track kind="subtitles" src="brave.en.vtt"> + </video> ``` ### [`v2.5.8`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#258) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.7...@biomejs/biome@2.5.8) ##### Patch Changes - [#&#8203;10710](https://github.com/biomejs/biome/pull/10710) [`0a0fbc1`](https://github.com/biomejs/biome/commit/0a0fbc15d67c410c80dfae398903f845544fcd65) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added a new nursery rule [`useReactCompiler`](https://biomejs.dev/linter/rules/use-react-compiler/), which reports diagnostics from React Compiler lint mode. - [#&#8203;11251](https://github.com/biomejs/biome/pull/11251) [`ea9dd8a`](https://github.com/biomejs/biome/commit/ea9dd8a93e65f849840415e8e26cd668aa1af913) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Improved performance of [`noImportCycles`](https://biomejs.dev/linter/rules/no-import-cycles/). - [#&#8203;11247](https://github.com/biomejs/biome/pull/11247) [`52b44d6`](https://github.com/biomejs/biome/commit/52b44d6795741d051bf703bd69c6cb447af8fd1d) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`noSvelteLegacyConst`](https://biomejs.dev/linter/rules/no-svelte-legacy-const/), which disallows legacy Svelte `{@const}` tags and recommends declaration tags with `$derived()`. Invalid: ```svelte {#each boxes as box} {@const area = box.width * box.height} <p>{area}</p> {/each} ``` Valid: ```svelte {#each boxes as box} {const area = $derived(box.width * box.height)} <p>{area}</p> {/each} ``` - [#&#8203;11252](https://github.com/biomejs/biome/pull/11252) [`d5f5704`](https://github.com/biomejs/biome/commit/d5f570414fdcdddf62372e35c05f6dababad9287) Thanks [@&#8203;Turtle-Hwan](https://github.com/Turtle-Hwan)! - Fixed [#&#8203;11250](https://github.com/biomejs/biome/issues/11250): [`useAwait`](https://biomejs.dev/linter/rules/use-await/) no longer reports async functions that contain an `await using` declaration. - [#&#8203;11143](https://github.com/biomejs/biome/pull/11143) [`6be7be1`](https://github.com/biomejs/biome/commit/6be7be1b147d7b4352ff5625a78bd54a48958950) Thanks [@&#8203;vznh](https://github.com/vznh)! - Fixed [#&#8203;11017](https://github.com/biomejs/biome/issues/11017): [`noUselessUndefined`](https://biomejs.dev/linter/rules/no-useless-undefined/) no longer reports `return undefined` when the enclosing function has a return type annotation other than `undefined` or `void`. - [#&#8203;11234](https://github.com/biomejs/biome/pull/11234) [`caefe39`](https://github.com/biomejs/biome/commit/caefe393c66340914c481f7ccfc82979cf76b61b) Thanks [@&#8203;subotac](https://github.com/subotac)! - Fixed [#&#8203;11228](https://github.com/biomejs/biome/issues/11228): CSS block comments between a declaration colon and value now preserve their source indentation. ```diff :root { --font-stack: -/* comment */ + /* comment */ system-ui; } ``` - [#&#8203;11285](https://github.com/biomejs/biome/pull/11285) [`bca1f73`](https://github.com/biomejs/biome/commit/bca1f73d939423056337bfd0a42cbdcb66bb1e3f) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Fixed [#&#8203;11280](https://github.com/biomejs/biome/issues/11280): CSS formatting keeps comments inside functional pseudo-classes and pseudo-elements instead of moving them before the function name. ```diff -:/* comment */ where(div) {} +:where(/* comment */ div) {} ``` - [#&#8203;11080](https://github.com/biomejs/biome/pull/11080) [`af16a0b`](https://github.com/biomejs/biome/commit/af16a0bf884c48bad2caab70e7930096e81e1c99) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - HTML `style` attribute values are now parsed as CSS. All Biome CSS lint rules are applied to the `style` attributes. - [#&#8203;11195](https://github.com/biomejs/biome/pull/11195) [`6a85588`](https://github.com/biomejs/biome/commit/6a85588578725195625281984a47c9a8563bf103) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed Svelte files failing to parse when an expression begins with an object literal. Now the following snippet is correctly parsed: ```svelte <p>{{ a: true }}</p> <div class={{ active: isActive }}></div> ``` - [#&#8203;11173](https://github.com/biomejs/biome/pull/11173) [`481d008`](https://github.com/biomejs/biome/commit/481d008f6e8872a78749496fbbf1f9c761d9a770) Thanks [@&#8203;Austin1serb](https://github.com/Austin1serb)! - Fixed [#&#8203;10242](https://github.com/biomejs/biome/issues/10242): JavaScript GritQL patterns with multiple metavariables now match snippets consistently in WebAssembly. - [#&#8203;11187](https://github.com/biomejs/biome/pull/11187) [`23c0369`](https://github.com/biomejs/biome/commit/23c0369c43b59284ca68c65883d6ede4228b6fb8) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Added the nursery rule [`noInvalidPropertyInitValue`](https://biomejs.dev/linter/rules/no-invalid-property-init-value/), 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>`: ```css @property --size { syntax: "<length>"; inherits: false; initial-value: red; } ``` - [#&#8203;11272](https://github.com/biomejs/biome/pull/11272) [`73896e6`](https://github.com/biomejs/biome/commit/73896e6712ba4c398ba21141829f8361ace45eb2) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Improved the diagnostic emitted by [`noRootType`](https://biomejs.dev/linter/rules/no-root-type). - [#&#8203;11240](https://github.com/biomejs/biome/pull/11240) [`bd0b68d`](https://github.com/biomejs/biome/commit/bd0b68d418890059930074b46273aa616fbb735a) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;11223](https://github.com/biomejs/biome/issues/11223): Improved the performance of [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises/) when analyzing async class methods that call other methods through `this`. - [#&#8203;11172](https://github.com/biomejs/biome/pull/11172) [`4a0bc5c`](https://github.com/biomejs/biome/commit/4a0bc5c46e6dbbefd17fa133ea426aa41f0a23f8) Thanks [@&#8203;saberoueslati](https://github.com/saberoueslati)! - Fixed [#&#8203;10806](https://github.com/biomejs/biome/issues/10806): [`noUselessFragments`](https://biomejs.dev/linter/rules/no-useless-fragments/) no longer causes Biome to panic when its unsafe fix removes a fragment used as a JSX attribute value. - [#&#8203;11227](https://github.com/biomejs/biome/pull/11227) [`4d603b0`](https://github.com/biomejs/biome/commit/4d603b072fae45a69bd291ab92f3379232cd34df) Thanks [@&#8203;saberoueslati](https://github.com/saberoueslati)! - Fixed [#&#8203;11178](https://github.com/biomejs/biome/issues/11178): [`noUndeclaredVariables`](https://biomejs.dev/linter/rules/no-undeclared-variables/) 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. - [#&#8203;11187](https://github.com/biomejs/biome/pull/11187) [`23c0369`](https://github.com/biomejs/biome/commit/23c0369c43b59284ca68c65883d6ede4228b6fb8) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed CSS parsing of registered custom properties: Biome now correctly validates the `syntax` descriptor of `@property` rules. ### [`v2.5.7`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#257) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.6...@biomejs/biome@2.5.7) ##### Patch Changes - [#&#8203;10822](https://github.com/biomejs/biome/pull/10822) [`c171b3b`](https://github.com/biomejs/biome/commit/c171b3bd513d49c35b66cdc74a5de0ca0766b6ef) Thanks [@&#8203;pkallos](https://github.com/pkallos)! - Added the option `ignoreIfStatements` to [useNullishCoalescing](https://biomejs.dev/linter/rules/use-nullish-coalescing/). 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. - [#&#8203;11136](https://github.com/biomejs/biome/pull/11136) [`e63354c`](https://github.com/biomejs/biome/commit/e63354cf280783fa6380951342bdacc3fd55e681) Thanks [@&#8203;AkashNaickar](https://github.com/AkashNaickar)! - Added a new nursery rule [`noExtendNative`](https://biomejs.dev/linter/rules/no-extend-native/), which reports extending the prototype of a built-in object. - [#&#8203;10094](https://github.com/biomejs/biome/pull/10094) [`e007143`](https://github.com/biomejs/biome/commit/e00714360807115210e549caca0f235431ca9a8a) Thanks [@&#8203;THEjacob1000](https://github.com/THEjacob1000)! - Added the nursery rule [`noTailwindArbitraryValue`](https://biomejs.dev/linter/rules/no-tailwind-arbitrary-value/). Biome now reports Tailwind CSS arbitrary values such as `w-[400px]`, including in HTML/JSX class attributes, configured utility functions, and tagged templates. - [#&#8203;11184](https://github.com/biomejs/biome/pull/11184) [`135f476`](https://github.com/biomejs/biome/commit/135f476de8b853f9dc2ff2679ea3525432e66e8e) Thanks [@&#8203;subotac](https://github.com/subotac)! - Fixed [#&#8203;11176](https://github.com/biomejs/biome/issues/11176): `noUnknownPseudoClass` now recognizes Vue's `:deep()` pseudo-class inside `.vue` style blocks. - [#&#8203;8239](https://github.com/biomejs/biome/pull/8239) [`a519f9d`](https://github.com/biomejs/biome/commit/a519f9d19e56015ec906efac4629fbb15708f5e2) Thanks [@&#8203;cormacrelf](https://github.com/cormacrelf)! - Fixed [#&#8203;8233](https://github.com/biomejs/biome/issues/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 ``` ```shell 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. - [#&#8203;11138](https://github.com/biomejs/biome/pull/11138) [`8c2c6bd`](https://github.com/biomejs/biome/commit/8c2c6bd96c035e506bc60b75448afb039e331fb1) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [`noUnnecessaryConditions`](https://biomejs.dev/linter/rules/no-unnecessary-conditions/): 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`: ```ts 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`: ```ts type Mapper<T> = () => T; declare function map<T>(mapper: Mapper<T>): T; map(() => 42) || flag; ``` - [#&#8203;11138](https://github.com/biomejs/biome/pull/11138) [`8c2c6bd`](https://github.com/biomejs/biome/commit/8c2c6bd96c035e506bc60b75448afb039e331fb1) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;11087](https://github.com/biomejs/biome/issues/11087): [`noUnnecessaryConditions`](https://biomejs.dev/linter/rules/no-unnecessary-conditions/) 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: ```ts declare const usage: { range: { startDate: string } } | null; const startDate = usage?.range.startDate ?? "N/A"; ``` - [#&#8203;11118](https://github.com/biomejs/biome/pull/11118) [`9c16840`](https://github.com/biomejs/biome/commit/9c16840801a806ba34fbba7da28b9724d250207a) Thanks [@&#8203;subotac](https://github.com/subotac)! - Fixed [#&#8203;11098](https://github.com/biomejs/biome/issues/11098): The HTML formatter now preserves the configured trailing newline when a file ends with a comment. ```diff -<!-- trailing comment --> \ No newline at end of file +<!-- trailing comment --> ``` - [#&#8203;11201](https://github.com/biomejs/biome/pull/11201) [`0e80610`](https://github.com/biomejs/biome/commit/0e8061069915651a6f7cbba918a0bde0dbc1491f) Thanks [@&#8203;Bishwas-py](https://github.com/Bishwas-py)! - Fixed [#&#8203;11182](https://github.com/biomejs/biome/issues/11182): suppression comments for [`noPositiveTabindex`](https://biomejs.dev/linter/rules/no-positive-tabindex/) now suppress the rule in HTML files when the attributes of the element span multiple lines. - [#&#8203;11079](https://github.com/biomejs/biome/pull/11079) [`607afd2`](https://github.com/biomejs/biome/commit/607afd2488efb30cff5ea4b27de4d98eca728e0f) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - 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: ```diff - <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 + " + /> ``` - [#&#8203;11156](https://github.com/biomejs/biome/pull/11156) [`fed72c7`](https://github.com/biomejs/biome/commit/fed72c7e8a2bff2942d5970f182262d18e049914) Thanks [@&#8203;saberoueslati](https://github.com/saberoueslati)! - Fixed [#&#8203;11129](https://github.com/biomejs/biome/issues/11129): [`noUnusedVariables`](https://biomejs.dev/linter/rules/no-unused-variables/) no longer reports Vue bindings as unused when they are assigned through automatically unwrapped template refs. - [#&#8203;11124](https://github.com/biomejs/biome/pull/11124) [`d890b39`](https://github.com/biomejs/biome/commit/d890b39c3ef21040bded453d9af91e1b301a0d67) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Fixed CSS formatting of line comments between a declaration colon and value to preserve their source indentation. ```diff .test { background: - /////// foo - // bar + /////// foo + // bar radial-gradient(circle, #&#8203;000, transparent); } ``` - [#&#8203;11113](https://github.com/biomejs/biome/pull/11113) [`3d8ab73`](https://github.com/biomejs/biome/commit/3d8ab73619f1c62a2d544d41ffee16eab9307d51) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Fixed CSS formatting of long block comments between comma-separated property values: ```diff .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; } ``` - [#&#8203;11127](https://github.com/biomejs/biome/pull/11127) [`da5c1a5`](https://github.com/biomejs/biome/commit/da5c1a539bac009eb1bc275b9bd8194f9ca7d5fa) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - The HTML formatter now picks the quote character for an attribute by counting the quotes in the value rather than looking only for a double quote. `&apos;` and `&quot;` count as the characters they stand for, and only the character that ends up as the delimiter stays escaped: ```diff - <div title='123 &apos;&quot; 456'></div> + <div title="123 '&quot; 456"></div> ``` Entities that are not quotes, such as `&amp;` or `&[#&#8203;39](https://github.com/biomejs/biome/issues/39);`, are left exactly as written. - [#&#8203;11193](https://github.com/biomejs/biome/pull/11193) [`77035bb`](https://github.com/biomejs/biome/commit/77035bb3777805c682eefa4cbed5464c94baccba) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed the HTML formatter collapsing the blank line between an element and the text that follows it. A blank line before text is now kept, the way one before another element already was: ```diff <div>foo</div> - text ``` - [#&#8203;11106](https://github.com/biomejs/biome/pull/11106) [`ad80f57`](https://github.com/biomejs/biome/commit/ad80f572c922fc2a80c90b8e26a66300dfb82d24) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - The HTML formatter now writes the HTML5 doctype in lowercase, matching Prettier: ```diff - <!DOCTYPE html> + <!doctype html> ``` This only applies to a plain `.html` file whose doctype stands alone. A doctype that names a DTD keeps the case it was written with, since the rest of the declaration is not lowercased either: ```html <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> ``` A `.vue`, `.svelte`, or `.astro` file keeps whatever the author wrote. - [#&#8203;11188](https://github.com/biomejs/biome/pull/11188) [`60679db`](https://github.com/biomejs/biome/commit/60679dbe6d53c9b78571042b0b8c906bd345e52d) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed the HTML formatter printing a comment twice when it ended the line of the last element in a document: ```diff - text<!-- a --><!-- a --> + text<!-- a --> ``` - [#&#8203;11077](https://github.com/biomejs/biome/pull/11077) [`4dcd0d9`](https://github.com/biomejs/biome/commit/4dcd0d99579650191696dc5fb8b16dd69d65c4ee) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed a bug where the HTML formatter collapsed the whitespace inside `<textarea>`, `<xmp>` and `<plaintext>`, changing what the page renders. ```diff - <textarea> - line one - line two </textarea> + <textarea>line one line two</textarea> ``` Biome now prints the content of these elements exactly as it appears in the source, matching the existing behavior for `<pre>`. - [#&#8203;11194](https://github.com/biomejs/biome/pull/11194) [`abfbb11`](https://github.com/biomejs/biome/commit/abfbb11da260852f0b4aa15f36207314ccfae436) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed the HTML formatter refusing to format a Svelte file containing an array pattern that skips a position: ```svelte {#each animals as [, value]} <p>{value}</p> {/each} ``` - [#&#8203;10094](https://github.com/biomejs/biome/pull/10094) [`e007143`](https://github.com/biomejs/biome/commit/e00714360807115210e549caca0f235431ca9a8a) Thanks [@&#8203;THEjacob1000](https://github.com/THEjacob1000)! - Fixed [`useSortedClasses`](https://biomejs.dev/linter/rules/use-sorted-classes/) to correctly detect unsorted classes in static member expression tagged templates (e.g. `tw.div\`...\`\`). Previously, these were silently skipped due to surrounding whitespace trivia not being stripped from the tag name. - [#&#8203;11078](https://github.com/biomejs/biome/pull/11078) [`10da30e`](https://github.com/biomejs/biome/commit/10da30e0013c35fe2f4d3e335b88a539ae6eb87a) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed Vue single-file components failing to parse when they contain a custom block such as `<i18n>` or `<docs>`, or a `<template>` written in another language. Their content is no longer read as HTML, so a block may hold whatever its own tooling expects: ```vue <docs> This block is prose, and it may mention a `<my-component>` without closing it. </docs> <template lang="pug"> .test #foo </template> ``` Previously both blocks produced a parse error and the whole file was left unformatted. Biome now prints their content unchanged while still formatting the opening tag. - [#&#8203;11231](https://github.com/biomejs/biome/pull/11231) [`4afd901`](https://github.com/biomejs/biome/commit/4afd901edd5d921d63a259a049c6a774269c7b82) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Improved the performance of the following lint rules: - [`noArguments`](https://biomejs.dev/linter/rules/no-arguments/). - [`noGlobalAssign`](https://biomejs.dev/linter/rules/no-global-assign/). - [`noUndeclaredVariables`](https://biomejs.dev/linter/rules/no-undeclared-variables/). - [`noRestrictedGlobals`](https://biomejs.dev/linter/rules/no-restricted-globals/). - [`noInvalidUseBeforeDeclaration`](https://biomejs.dev/linter/rules/no-invalid-use-before-declaration/). - [`noShadow`](https://biomejs.dev/linter/rules/no-shadow/). - [`noRedeclare`](https://biomejs.dev/linter/rules/no-redeclare/). - [#&#8203;11134](https://github.com/biomejs/biome/pull/11134) [`2fa0a62`](https://github.com/biomejs/biome/commit/2fa0a62224af7a13869a28ef80aefa5ea75ebfd2) Thanks [@&#8203;yanthomasdev](https://github.com/yanthomasdev)! - Clarified the warning emitted when using the experimental `json` and `json-pretty` reporters. - [#&#8203;11198](https://github.com/biomejs/biome/pull/11198) [`ed88b13`](https://github.com/biomejs/biome/commit/ed88b13a6d95fe564aaee6c731651e7dec8266db) Thanks [@&#8203;saberoueslati](https://github.com/saberoueslati)! - Fixed [#&#8203;11171](https://github.com/biomejs/biome/issues/11171): variables referenced only inside a Svelte attachment (`{@attach ...}`) are no longer reported as unused by [`noUnusedVariables`](https://biomejs.dev/linter/rules/no-unused-variables/) and [`noUnusedImports`](https://biomejs.dev/linter/rules/no-unused-imports/). - [#&#8203;11155](https://github.com/biomejs/biome/pull/11155) [`6ee17ea`](https://github.com/biomejs/biome/commit/6ee17ea2df979a67df5d1263734f28f77c6512a6) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Improved performance when printing diagnostics to the console. - [#&#8203;11160](https://github.com/biomejs/biome/pull/11160) [`217f8ad`](https://github.com/biomejs/biome/commit/217f8adbc2f700ab4c92cb227434c2afba9f9611) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Improved the performance of [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/) by skipping type inference for assignment statements, which are always considered handled. - [#&#8203;11159](https://github.com/biomejs/biome/pull/11159) [`26c23d9`](https://github.com/biomejs/biome/commit/26c23d96ced1a6eca496955fbe93279da2747346) Thanks [@&#8203;saberoueslati](https://github.com/saberoueslati)! - Fixed [#&#8203;11144](https://github.com/biomejs/biome/issues/11144): [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/) no longer reports already-awaited optional Promise values. - [#&#8203;11138](https://github.com/biomejs/biome/pull/11138) [`8c2c6bd`](https://github.com/biomejs/biome/commit/8c2c6bd96c035e506bc60b75448afb039e331fb1) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;11121](https://github.com/biomejs/biome/issues/11121): [`noUnnecessaryConditions`](https://biomejs.dev/linter/rules/no-unnecessary-conditions/) no longer reports conditions based on an inapplicable function overload. For example, the condition in the following code is no longer reported because `query({})` selects the overload that returns `boolean`: ```ts declare function query(options: { initial: string }): { isPending: false }; declare function query(options: { initial?: string }): { isPending: boolean }; const { isPending } = query({}); isPending || fallback; ``` - [#&#8203;11152](https://github.com/biomejs/biome/pull/11152) [`c4fc6a9`](https://github.com/biomejs/biome/commit/c4fc6a90777358905cf99b3261a479de73d7d383) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Improved the performance of collecting rule timings with `--profile-rules` in heavily multithreaded environments. - [#&#8203;11128](https://github.com/biomejs/biome/pull/11128) [`4d3ff76`](https://github.com/biomejs/biome/commit/4d3ff7689c36af5149142d9a4a23165154359655) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;7635](https://github.com/biomejs/biome/issues/7635): [`noDeprecatedImports`](https://biomejs.dev/linter/rules/no-deprecated-imports/) now detects deprecated ambient declarations that are exported separately. - [#&#8203;11117](https://github.com/biomejs/biome/pull/11117) [`01f7ef5`](https://github.com/biomejs/biome/commit/01f7ef58d4c19a587b01754c96b577a2a5a47418) Thanks [@&#8203;subotac](https://github.com/subotac)! - Fixed [#&#8203;11014](https://github.com/biomejs/biome/issues/11014): [`noDelete`](https://biomejs.dev/linter/rules/no-delete/) no longer reports `process.env["FOO"]` style property deletions. - [#&#8203;11168](https://github.com/biomejs/biome/pull/11168) [`9847e68`](https://github.com/biomejs/biome/commit/9847e680ff8bb891a6c910e881af98a4fffa33c2) Thanks [@&#8203;saberoueslati](https://github.com/saberoueslati)! - Added the nursery rule [`noNonScalableViewport`](https://biomejs.dev/linter/rules/no-non-scalable-viewport), which reports viewport metadata that disables user scaling with `user-scalable=no`. For example: ```html <meta name="viewport" content="width=device-width, user-scalable=no" /> ``` - [#&#8203;11154](https://github.com/biomejs/biome/pull/11154) [`a1d6b1f`](https://github.com/biomejs/biome/commit/a1d6b1fc544c6c6cc1dd38f87898d34738fbe97b) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Improved the performance of [`noImportCycles`](https://biomejs.dev/linter/rules/no-import-cycles/) by skipping graph traversals for imports that cannot be part of a cycle. - [#&#8203;11175](https://github.com/biomejs/biome/pull/11175) [`d96d6dd`](https://github.com/biomejs/biome/commit/d96d6dd07702828f7e7a5ce59f8fc00006f6ee46) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed CSS parsing of registered custom properties: Biome now correctly validates the `syntax` descriptor of `@property` rules. ### [`v2.5.6`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#256) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.5...@biomejs/biome@2.5.6) ##### Patch Changes - [#&#8203;11035](https://github.com/biomejs/biome/pull/11035) [`0e4b03b`](https://github.com/biomejs/biome/commit/0e4b03be71b32120c6326e58e046260bcf5d3231) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed a performance regression in [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises/) that caused type inference to run repeatedly while linting a file. - [#&#8203;11043](https://github.com/biomejs/biome/pull/11043) [`22ec076`](https://github.com/biomejs/biome/commit/22ec076462d4590ea7c95f7693b69040c32a38aa) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Fixed CSS formatting for multiline function arguments preceded by comments: ```diff .example { value: outer( 1, /* comment */ nested( - first, - second - ) + first, + second + ) ); } ``` - [#&#8203;11007](https://github.com/biomejs/biome/pull/11007) [`c9acb25`](https://github.com/biomejs/biome/commit/c9acb25acbce7a6f632b5041ec546a604aea4343) Thanks [@&#8203;BTF-Kabir-2020](https://github.com/BTF-Kabir-2020)! - Fixed [#&#8203;9195](https://github.com/biomejs/biome/issues/9195): [`useHookAtTopLevel`](https://biomejs.dev/linter/rules/use-hook-at-top-level/) no longer reports hooks in named `forwardRef` components that receive a `ref` parameter. - [#&#8203;10152](https://github.com/biomejs/biome/pull/10152) [`50a9bd8`](https://github.com/biomejs/biome/commit/50a9bd84df852de305e94a91fb57f6b3b1378187) Thanks [@&#8203;Zelys-DFKH](https://github.com/Zelys-DFKH)! - Fixed [#&#8203;10131](https://github.com/biomejs/biome/issues/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`. - [#&#8203;11105](https://github.com/biomejs/biome/pull/11105) [`8ffe2b9`](https://github.com/biomejs/biome/commit/8ffe2b9f2f9224921a0bad4a772e6611006351e5) Thanks [@&#8203;dadavidtseng](https://github.com/dadavidtseng)! - Fixed [#&#8203;11092](https://github.com/biomejs/biome/issues/11092): The [`noUselessTernary`](https://biomejs.dev/linter/rules/no-useless-ternary/) quick fix now preserves operator spacing when simplifying or inverting boolean ternary expressions. - [#&#8203;10533](https://github.com/biomejs/biome/pull/10533) [`5809875`](https://github.com/biomejs/biome/commit/580987506a32cdde2f5498e0f712e3493ef9adde) Thanks [@&#8203;Mokto](https://github.com/Mokto)! - Fixed [#&#8203;10515](https://github.com/biomejs/biome/issues/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. - [#&#8203;11040](https://github.com/biomejs/biome/pull/11040) [`0abb620`](https://github.com/biomejs/biome/commit/0abb620b2f0bd748bf272a2bc56aa02f5a6d0fee) Thanks [@&#8203;Mokto](https://github.com/Mokto)! - 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. - [#&#8203;10858](https://github.com/biomejs/biome/pull/10858) [`6d18204`](https://github.com/biomejs/biome/commit/6d182043b1de76f8668464bfa5c295161135ee0e) Thanks [@&#8203;ruidosujeira](https://github.com/ruidosujeira)! - Fixed [#&#8203;10839](https://github.com/biomejs/biome/issues/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. - [#&#8203;11009](https://github.com/biomejs/biome/pull/11009) [`2c36626`](https://github.com/biomejs/biome/commit/2c36626bed58e63e49ecca8a40c717adae4c91ac) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Improved the accuracy of type-aware lint rules by resolving more inferred types. For example, [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/) now detects floating Promises returned by aliased callbacks and arrays of Promises created by async mapping callbacks. The following statements are now reported: ```ts type AsyncCallback = () => Promise<void>; declare const callback: AsyncCallback; callback(); [1, 2, 3].map(async (value) => value); ``` - [#&#8203;10973](https://github.com/biomejs/biome/pull/10973) [`9cb044c`](https://github.com/biomejs/biome/commit/9cb044cf2c8971642942c302a6d2b0000964c2f0) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed false positives in [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) 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: ```ts function unresolvedReturnType(): MissingType { return "value" as const; } ``` - [#&#8203;11071](https://github.com/biomejs/biome/pull/11071) [`15047a2`](https://github.com/biomejs/biome/commit/15047a2fff2aa2a5c0c096257b4718b0141431be) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - The HTML parser now accepts mixed-case `doctype` declarations. - [#&#8203;11030](https://github.com/biomejs/biome/pull/11030) [`cc90e65`](https://github.com/biomejs/biome/commit/cc90e65a6b14388a5fab1d893f782055fac34f91) Thanks [@&#8203;marschattha](https://github.com/marschattha)! - The `rdjson` reporter now populates the [severity](https://github.com/reviewdog/reviewdog/blob/master/proto/rdf/reviewdog.proto) field of each diagnostic (`ERROR`, `WARNING`, or `INFO`), so tools consuming Reviewdog Diagnostic Format output no longer need to assume a default severity. - [#&#8203;11009](https://github.com/biomejs/biome/pull/11009) [`2c36626`](https://github.com/biomejs/biome/commit/2c36626bed58e63e49ecca8a40c717adae4c91ac) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed a performance regression in type-aware JavaScript lint rules by inferring only requested types and memoizing export resolution. - [#&#8203;11056](https://github.com/biomejs/biome/pull/11056) [`903b177`](https://github.com/biomejs/biome/commit/903b1770528040484b5f8b71f652130a8e6bd960) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added support for Svelte declaration tags using `let` and `const`. Biome can now parse, format, and lint bindings declared in these tags. - [#&#8203;11045](https://github.com/biomejs/biome/pull/11045) [`89c27c6`](https://github.com/biomejs/biome/commit/89c27c62541d2b628247563441e48f2303e53f4b) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Improved the performance of Biome formatter up to \~7% across the board. - [#&#8203;9806](https://github.com/biomejs/biome/pull/9806) [`781d68d`](https://github.com/biomejs/biome/commit/781d68dae5df6ad188efc8afb0972112654614fe) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`noJsRestrictedProperties`](https://biomejs.dev/linter/rules/no-js-restricted-properties/), 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. ### [`v2.5.5`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#255) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.4...@biomejs/biome@2.5.5) ##### Patch Changes - [#&#8203;10972](https://github.com/biomejs/biome/pull/10972) [`ab8c21b`](https://github.com/biomejs/biome/commit/ab8c21b35e81708276e4283a4a0ff86ea815e345) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [`useExhaustiveSwitchCases`](https://biomejs.dev/linter/rules/use-exhaustive-switch-cases/) 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: ```ts declare const value: 1n | 2n; switch (value) { case 1n: break; } ``` - [#&#8203;10972](https://github.com/biomejs/biome/pull/10972) [`ab8c21b`](https://github.com/biomejs/biome/commit/ab8c21b35e81708276e4283a4a0ff86ea815e345) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed false positives in [`noBaseToString`](https://biomejs.dev/linter/rules/no-base-to-string/) and [`useNullishCoalescing`](https://biomejs.dev/linter/rules/use-nullish-coalescing/) 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: ```ts type Recursive = Recursive; declare const value: Recursive; String(value); value || "fallback"; ``` - [#&#8203;10977](https://github.com/biomejs/biome/pull/10977) [`0bf7486`](https://github.com/biomejs/biome/commit/0bf748653e488d0b959d39847641438cdb28188b) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;10922](https://github.com/biomejs/biome/issues/10922): the action [`useSortedAttributes`](https://biomejs.dev/assist/actions/use-sorted-attributes/) no longer triggers for HTML instructions. - [#&#8203;10957](https://github.com/biomejs/biome/pull/10957) [`cf263c4`](https://github.com/biomejs/biome/commit/cf263c4700e9f24115e541d1f142934a9b2d878f) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [`noThenProperty`](https://biomejs.dev/linter/rules/no-then-property/) failing to detect `Object.fromEntries`, `Object.defineProperty`, and `Reflect.defineProperty` calls with comments between their tokens. - [#&#8203;10983](https://github.com/biomejs/biome/pull/10983) [`edc0ed7`](https://github.com/biomejs/biome/commit/edc0ed738ab8da3d512d527196684bd668090854) Thanks [@&#8203;ayaangazali](https://github.com/ayaangazali)! - Fixed [#&#8203;10980](https://github.com/biomejs/biome/issues/10980): [`useAriaPropsSupportedByRole`](https://biomejs.dev/linter/rules/use-aria-props-supported-by-role/) 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`. - [#&#8203;10889](https://github.com/biomejs/biome/pull/10889) [`89526e3`](https://github.com/biomejs/biome/commit/89526e3858c437408ec9ff192c35a866ad991d1b) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Fixed CSS formatter casing for syntax-owned names while preserving author-defined names, including scoped keyframes and container scroll-state queries. ```diff - 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; } } ``` - [#&#8203;10964](https://github.com/biomejs/biome/pull/10964) [`794ccd0`](https://github.com/biomejs/biome/commit/794ccd0528345c4eaa87af1d86f02475277a0a22) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Fixed CSS formatting for comments between declaration values and `!important`. ```diff -a { color: /* before */ /* after */ red !important; } +a { color: /* before */ red /* after */ !important; } ``` - [#&#8203;10993](https://github.com/biomejs/biome/pull/10993) [`b7a9694`](https://github.com/biomejs/biome/commit/b7a969425d4292fc7c50440da7aea41ce5c9a9c2) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Fixed the CSS formatter to preserve comments on the correct side of selector combinators and before declaration blocks. ```diff -.before > /* comment */ .after {} +.before /* comment */ > .after {} ``` It now also keeps selectors with escaped newlines in attribute values inline when they fit. ```diff -div - span[foo="bar\ +div span[foo="bar\ value"] {} ``` - [#&#8203;10978](https://github.com/biomejs/biome/pull/10978) [`8ebafe1`](https://github.com/biomejs/biome/commit/8ebafe1c7489f1f7af379b8e52b8ad063c82d28a) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;10870](https://github.com/biomejs/biome/issues/10870): [`noUnresolvedImports`](https://biomejs.dev/linter/rules/no-unresolved-imports/) no longer reports false positives such as `import type { NextRequest } from "next/server"`. - [#&#8203;10901](https://github.com/biomejs/biome/pull/10901) [`68c10e6`](https://github.com/biomejs/biome/commit/68c10e672fc886b31423b18be01e873d3bf77f43) Thanks [@&#8203;Socialpranker](https://github.com/Socialpranker)! - Fixed [#&#8203;10622](https://github.com/biomejs/biome/issues/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. - [#&#8203;10936](https://github.com/biomejs/biome/pull/10936) [`7df46f5`](https://github.com/biomejs/biome/commit/7df46f5be0880a02cb37453f01b83c1ba59b1e44) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Improved generic tuple inference for [`useIncludes`](https://biomejs.dev/linter/rules/use-includes/). The rule now recognizes specialised tuple element types returned through generic aliases. - [#&#8203;10941](https://github.com/biomejs/biome/pull/10941) [`f787725`](https://github.com/biomejs/biome/commit/f7877258271e20523d5c673e62912fce1d85cd56) Thanks [@&#8203;siketyan](https://github.com/siketyan)! - Fixed [`#10855`](https://github.com/biomejs/biome/issues/10855): Biome now supports parsing and formatting CSS custom media queries declared with [`@custom-media`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@custom-media). - [#&#8203;10969](https://github.com/biomejs/biome/pull/10969) [`72d309b`](https://github.com/biomejs/biome/commit/72d309b655cee70473e20b061f5a45112139688c) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed an issue where Biome logs became too verbose, dumping information not relevant to user's operations. - [`e62f6b6`](https://github.com/biomejs/biome/commit/e62f6b61461227bbfd57fdf1b50b2dc8c01ea5a0) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;10963](https://github.com/biomejs/biome/issues/10963): Biome no longer panics when a type-aware rule such as [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/) checks a call to a function with multiple call signatures imported from another module. - [#&#8203;10931](https://github.com/biomejs/biome/pull/10931) [`899c60d`](https://github.com/biomejs/biome/commit/899c60d506115b3f62030236cbd0901bf294e6ab) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed `check --write` command. Now the command reports code frame of the formatted code, if the formatter is enabled. - [#&#8203;10904](https://github.com/biomejs/biome/pull/10904) [`ceee4f4`](https://github.com/biomejs/biome/commit/ceee4f43dabf88d86b87c9a4ce6051b6738869c2) Thanks [@&#8203;qzwxsaedc](https://github.com/qzwxsaedc)! - Fixed [#&#8203;10892](https://github.com/biomejs/biome/issues/10892): [`noUnnecessaryConditions`](https://biomejs.dev/linter/rules/no-unnecessary-conditions/) no longer reports a false positive when checking a member of a discriminated union that is accessed through a default type-only namespace import. The following code is no longer flagged: ```ts import type Types from "./types"; declare function parse(): Types.Result<string>; const result = parse(); if (!result.success) { } ``` - [#&#8203;10962](https://github.com/biomejs/biome/pull/10962) [`f0a67f2`](https://github.com/biomejs/biome/commit/f0a67f2e56c0785595c5cf14a93dba5bb32acf2d) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Biome no longer removes embedded styles and scripts in HTML files. - [#&#8203;11000](https://github.com/biomejs/biome/pull/11000) [`5039a1e`](https://github.com/biomejs/biome/commit/5039a1ee35771d0193de65a6326781313ab77afb) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed a bug where closing one editor stopped a shared Biome daemon used by other editors. LSP proxy processes now exit when either the editor or daemon disconnects. - [#&#8203;10957](https://github.com/biomejs/biome/pull/10957) [`cf263c4`](https://github.com/biomejs/biome/commit/cf263c4700e9f24115e541d1f142934a9b2d878f) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Improved the performance of the [`noThenProperty`](https://biomejs.dev/linter/rules/no-then-property/) lint rule by about 50%. - [#&#8203;10992](https://github.com/biomejs/biome/pull/10992) [`4bf9b21`](https://github.com/biomejs/biome/commit/4bf9b21319df240e2c5ef2e5a9cb2e9582a0e1d1) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises/): The rule now reports Promise-returning callbacks where a synchronous callback is expected when calls use tuple spreads or tuple rest parameters, including generic and deeply nested tuples, and when constructor signatures come from interface or object types. Recursive or excessively nested tuple spreads use a conservative fallback so analysis terminates. For example, the following callback is now reported. ```ts declare function consume(...args: [number, () => void]): void; const prefix: [number] = [1]; consume(...prefix, async () => {}); ``` - [#&#8203;10915](https://github.com/biomejs/biome/pull/10915) [`b3b12b3`](https://github.com/biomejs/biome/commit/b3b12b3fe390feabbd9ba097922d6c7e56823406) Thanks [@&#8203;Functionhx](https://github.com/Functionhx)! - Added the rule [`noNegationInEqualityCheck`](https://biomejs.dev/linter/rules/no-negation-in-equality-check/). The rule flags negated expressions on the left side of strict equality checks like `!foo === bar` — due to operator precedence this evaluates as `(!foo) === bar` which is almost always a mistake for `foo !== bar`. The rule provides an unsafe fix that flips the operator. ```js // Invalid !foo === bar; !foo !== bar; // Valid foo !== bar; foo === bar; ``` - [#&#8203;10970](https://github.com/biomejs/biome/pull/10970) [`bd1038b`](https://github.com/biomejs/biome/commit/bd1038be1ad110aae60bcdbe9a154c6a2fc85c14) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Improved overload selection for [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises/). Biome now handles overloaded calls, overloaded constructors, rest parameters, union arguments, and generic constraints without selecting an incompatible signature. For example, `noMisusedPromises` now reports the async callback passed to the synchronous overload: ```ts declare function consume(kind: "async", callback: () => Promise<void>): void; declare function consume(kind: "sync", callback: () => void): void; consume("sync", async () => {}); ``` - [#&#8203;10933](https://github.com/biomejs/biome/pull/10933) [`48a4abb`](https://github.com/biomejs/biome/commit/48a4abb99d41b1241b2a5812a12247b671d0dfed) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [`useArrayFind`](https://biomejs.dev/linter/rules/use-array-find/) to recognize bigint zero indexes. - [#&#8203;10931](https://github.com/biomejs/biome/pull/10931) [`899c60d`](https://github.com/biomejs/biome/commit/899c60d506115b3f62030236cbd0901bf294e6ab) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed an orchestration issue that could lead to deadlocks when type-aware rules are enabled. - [#&#8203;10969](https://github.com/biomejs/biome/pull/10969) [`72d309b`](https://github.com/biomejs/biome/commit/72d309b655cee70473e20b061f5a45112139688c) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Hardened the Biome Language Server by improving its synchronisation logic. - [#&#8203;10972](https://github.com/biomejs/biome/pull/10972) [`ab8c21b`](https://github.com/biomejs/biome/commit/ab8c21b35e81708276e4283a4a0ff86ea815e345) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed false positives in [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises/) and [`useAwaitThenable`](https://biomejs.dev/linter/rules/use-await-thenable/) when Promise or thenable inference cannot complete. These rules now suppress diagnostics instead of treating incomplete type information as a definite result. For example, `useAwaitThenable` no longer reports `await value` when the value's thenability is unknown: ```ts declare const value: unknown; async function consume() { await value; } ``` ### [`v2.5.4`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#254) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.3...@biomejs/biome@2.5.4) ##### Patch Changes - [#&#8203;10665](https://github.com/biomejs/biome/pull/10665) [`55ff995`](https://github.com/biomejs/biome/commit/55ff995098148446b7e7fdfc19053902bb987122) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Improved the performance of the HTML parser slightly in our synthetic benchmarks. - [#&#8203;10894](https://github.com/biomejs/biome/pull/10894) [`f4fb10e`](https://github.com/biomejs/biome/commit/f4fb10e176e537e8ce2cac0c3fd4c38a77f91886) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;6392](https://github.com/biomejs/biome/issues/6392): On-type formatting no longer moves comments before an `if` statement into its body. - [#&#8203;10939](https://github.com/biomejs/biome/pull/10939) [`f2799db`](https://github.com/biomejs/biome/commit/f2799db38e3d8a644207d9b8f957abea6cb3d9fa) Thanks [@&#8203;Netail](https://github.com/Netail)! - Fixed [#&#8203;10930](https://github.com/biomejs/biome/issues/10930): [`noLabelWithoutControl`](https://biomejs.dev/linter/rules/no-label-without-control/) now correctly detects text interpolation in Astro, Svelte & Vue as valid accessible content. - [#&#8203;10945](https://github.com/biomejs/biome/pull/10945) [`ae15d98`](https://github.com/biomejs/biome/commit/ae15d98bbf2222fbb34e3e31832cba9676a6d01c) Thanks [@&#8203;Netail](https://github.com/Netail)! - Fixed [#&#8203;10942](https://github.com/biomejs/biome/issues/10942): Svelte directives don't throw an accidental debug log anymore. - [#&#8203;10842](https://github.com/biomejs/biome/pull/10842) [`5e1abfe`](https://github.com/biomejs/biome/commit/5e1abfee59155b5fdca8813314371ed54c06acfb) Thanks [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562)! - Fixed [#&#8203;9196](https://github.com/biomejs/biome/issues/9196): `biome check --write --unsafe` no longer hangs forever when applying the [`noCommentText`](https://biomejs.dev/linter/rules/no-comment-text/) code fix. The rule's fix now wraps the comment in a real JSX expression container (`{/* comment */}`) instead of re-inserting the braces as plain JSX text, so the fixed code is no longer reported again by the same rule. - [#&#8203;10891](https://github.com/biomejs/biome/pull/10891) [`ecca79e`](https://github.com/biomejs/biome/commit/ecca79e8ff10f40aa676212c0db0a970c6091615) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [`#10885`](https://github.com/biomejs/biome/issues/10885): prevented a module-inference regression introduced by a housekeeping change. - [#&#8203;10886](https://github.com/biomejs/biome/pull/10886) [`60c8043`](https://github.com/biomejs/biome/commit/60c8043527f7ccc7b505471e1042f2a4324e4d31) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10727](https://github.com/biomejs/biome/issues/10727): Biome now breaks the arguments of curried `test.each`, `it.each`, `describe.each`, and `test.for` calls when they exceed the configured line width. ```diff - test.each([[1, 2]])("a description that is long enough to push the hugged opening line beyond the print width", (a, b) => { - expect(a).toBe(b); - }); + test.each([[1, 2]])( + "a description that is long enough to push the hugged opening line beyond the print width", + (a, b) => { + expect(a).toBe(b); + }, + ); ``` - [#&#8203;10895](https://github.com/biomejs/biome/pull/10895) [`01a85f0`](https://github.com/biomejs/biome/commit/01a85f04b09f0af05b16a15c137421e312ceada5) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Biome will now remove stale Unix daemon sockets from older Biome versions when starting a newer daemon. ### [`v2.5.3`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#253) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.2...@biomejs/biome@2.5.3) ##### Patch Changes - [#&#8203;10815](https://github.com/biomejs/biome/pull/10815) [`86613d5`](https://github.com/biomejs/biome/commit/86613d5b01eb965b460ccefbf27f168d87774aaf) Thanks [@&#8203;WaterWhisperer](https://github.com/WaterWhisperer)! - Fixed a parser panic reported in [#&#8203;10708](https://github.com/biomejs/biome/issues/10708): Biome now recovers when unsupported CSS Modules `@value` rules or scoped `@keyframes` names end at EOF. - [#&#8203;10534](https://github.com/biomejs/biome/pull/10534) [`da9b403`](https://github.com/biomejs/biome/commit/da9b403b6bbacc8d75d56e327a46f4ed0285913e) Thanks [@&#8203;Mokto](https://github.com/Mokto)! - Fixed [`noUnusedVariables`](https://biomejs.dev/linter/rules/no-unused-variables/) false positives in Svelte files: Svelte store subscriptions (`$store` references in templates now keep the underlying `store` binding from being flagged), and `$bindable()` props that are only written to in the script block (write-only is intentional for bindable props) are no longer reported as unused. - [#&#8203;10827](https://github.com/biomejs/biome/pull/10827) [`098ba41`](https://github.com/biomejs/biome/commit/098ba41c99e6efaac8eb182eec258a567bb00123) Thanks [@&#8203;Aqu1bp](https://github.com/Aqu1bp)! - Fixed [#&#8203;10698](https://github.com/biomejs/biome/issues/10698): The [`noUnsafeOptionalChaining`](https://biomejs.dev/linter/rules/no-unsafe-optional-chaining/) rule now reports unsafe optional chains wrapped in TypeScript `as`, `satisfies`, type assertion, and instantiation expressions, such as `new (value?.constructor as Constructor)()`. - [#&#8203;10773](https://github.com/biomejs/biome/pull/10773) [`3c6513d`](https://github.com/biomejs/biome/commit/3c6513d4e9a82a195785144caa9d96093c3861ff) Thanks [@&#8203;otkrickey](https://github.com/otkrickey)! - Fixed [#&#8203;10772](https://github.com/biomejs/biome/issues/10772): [`useVueValidVOn`](https://biomejs.dev/linter/rules/use-vue-valid-v-on/) no longer reports a missing handler for v-on directives using a verb modifier (`.stop` / `.prevent`) without an expression, e.g. `<div @click.stop></div>`. The rule also accepts the arg-less object syntax `<div v-on="$listeners"></div>` instead of reporting a missing event name. - [#&#8203;10721](https://github.com/biomejs/biome/pull/10721) [`d83c66b`](https://github.com/biomejs/biome/commit/d83c66b39a820703d94100f8a6502cc6dbad26a1) Thanks [@&#8203;minseong0324](https://github.com/minseong0324)! - Improved type-aware lint rule inference for built-in globals and indexed function calls. Biome now resolves `Error(...)`, `new Error(...)`, optional `Error#stack`, and calls through indexed function values such as `handlers[0]()` more accurately. - [#&#8203;10865](https://github.com/biomejs/biome/pull/10865) [`6450276`](https://github.com/biomejs/biome/commit/6450276764ee4794a0fcb46c139f95b68d892427) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;10845](https://github.com/biomejs/biome/issues/10845). Biome Language Server no longer goes in deadlock when the scanner is enabled. - [#&#8203;10853](https://github.com/biomejs/biome/pull/10853) [`93d8e53`](https://github.com/biomejs/biome/commit/93d8e5352454bccfbd179db03b3155776599c52c) Thanks [@&#8203;Netail](https://github.com/Netail)! - Fixed [#&#8203;10840](https://github.com/biomejs/biome/issues/10840): Astro shorthand attribute syntax is now correctly being parsed from embedded nodes. - [#&#8203;10820](https://github.com/biomejs/biome/pull/10820) [`bba3092`](https://github.com/biomejs/biome/commit/bba30920715920142e933939f6270feedca933a5) Thanks [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562)! - Fixed [#&#8203;10619](https://github.com/biomejs/biome/issues/10619): [`noProcessEnv`](https://biomejs.dev/linter/rules/no-process-env/) now also reports computed (bracket) member access. Previously only dot access was checked, so `process["env"]` and `env["NODE_ENV"]` (where `env` is imported from `node:process`) were missed. Both static and computed accesses are now reported. - [#&#8203;10835](https://github.com/biomejs/biome/pull/10835) [`3447b2f`](https://github.com/biomejs/biome/commit/3447b2f5a3c430efc8e917514260af5341c5509d) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10824](https://github.com/biomejs/biome/issues/10824): [`useDomQuerySelector`](https://biomejs.dev/linter/rules/use-dom-query-selector/) now supports an `ignore` option for receiver identifiers that should not be reported. - [#&#8203;10875](https://github.com/biomejs/biome/pull/10875) [`b12e486`](https://github.com/biomejs/biome/commit/b12e486d0f0b80d02d2208e239190f8756d39d48) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10795](https://github.com/biomejs/biome/issues/10795): `--profile-rules` now reports timings for each plugin separately as `plugin/<pluginName>`, matching the naming used by plugin suppressions, instead of aggregating all plugins under a single `plugin/plugin` entry. - [#&#8203;10877](https://github.com/biomejs/biome/pull/10877) [`d6bc447`](https://github.com/biomejs/biome/commit/d6bc4473a210758ee49f6cad41bc69587a7cf125) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [biome-zed#164](https://github.com/biomejs/biome-zed/issues/164): Biome no longer inserts stray whitespace when format-on-type runs after closing delimiters such as `)`, `]`, and `}`. - [#&#8203;10867](https://github.com/biomejs/biome/pull/10867) [`a21463e`](https://github.com/biomejs/biome/commit/a21463e5f616a2db5035b470cd206ac9da4d9423) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10864](https://github.com/biomejs/biome/issues/10864): Biome no longer crashes when checking or linting HTML files with unquoted attribute values such as `<textarea rows=4></textarea>`. ### [`v2.5.2`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#252) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.1...@biomejs/biome@2.5.2) ##### Patch Changes - [#&#8203;10595](https://github.com/biomejs/biome/pull/10595) [`f458028`](https://github.com/biomejs/biome/commit/f4580289094a8fe5c85252adc3399c060bab811e) Thanks [@&#8203;pkallos](https://github.com/pkallos)! - Added the option `ignoreBooleanCoercion` to [useNullishCoalescing](https://biomejs.dev/linter/rules/use-nullish-coalescing/). When enabled, Biome ignores `||` and `||=` used inside a `Boolean()` call, where coalescing on falsy values is intentional. - [#&#8203;10798](https://github.com/biomejs/biome/pull/10798) [`4a32b63`](https://github.com/biomejs/biome/commit/4a32b63eb41f144dc8faf6b5cdb05e1de5dbcb63) Thanks [@&#8203;pkallos](https://github.com/pkallos)! - Added the option `ignorePrimitives` to [useNullishCoalescing](https://biomejs.dev/linter/rules/use-nullish-coalescing/). When enabled, Biome ignores `||`, `||=`, and ternary expressions whose non-nullish operands are all primitives the option opts out of. Use `true` to ignore all primitives, or an object selecting `string`, `number`, `boolean`, or `bigint`. - [#&#8203;10545](https://github.com/biomejs/biome/pull/10545) [`f3d4c00`](https://github.com/biomejs/biome/commit/f3d4c0082676c5188e9a6aa516318c7e3d59bda6) Thanks [@&#8203;Mokto](https://github.com/Mokto)! - Added the new nursery rule [`noSvelteUnnecessaryStateWrap`](https://biomejs.dev/linter/rules/no-svelte-unnecessary-state-wrap/), which reports unnecessary `$state()` wrapping of classes from `svelte/reactivity` that are already reactive. ```svelte <script> import { SvelteMap } from "svelte/reactivity"; const map = $state(new SvelteMap()); // redundant </script> ``` - [#&#8203;10752](https://github.com/biomejs/biome/pull/10752) [`f62fb8b`](https://github.com/biomejs/biome/commit/f62fb8b53092fe85e16f9d4ea0e584fee7031ab5) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;10739](https://github.com/biomejs/biome/issues/10739). Now the rule [`useValidAutocomplete`](https://biomejs.dev/linter/rules/use-valid-autocomplete/) correctly flags the `autoComplete` attribute. - [#&#8203;10796](https://github.com/biomejs/biome/pull/10796) [`f1b3ab2`](https://github.com/biomejs/biome/commit/f1b3ab2c09522a52c93f669ce679675237b96813) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;10768](https://github.com/biomejs/biome/issues/10768). Improved the performance of the Biome Language Server by cancelling certain in-flight operations when there are fast updates. - [#&#8203;10719](https://github.com/biomejs/biome/pull/10719) [`aa649b5`](https://github.com/biomejs/biome/commit/aa649b586a2221bf058af7ce80af6faa11faf846) Thanks [@&#8203;minseong0324](https://github.com/minseong0324)! - Fixed [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) false positive on returns that use a widening type assertion: `"a" as string` is no longer reported as misleading. The rule now also reports a literal-pinning assertion such as `false as false`, matching the existing `as const` behavior. ```ts // No longer flagged (returns are `string`): function getValue(b: boolean): string { if (b) return "a" as string; return "b" as string; } // Now also reported, like `as const` (returns `false`): function isReady(): boolean { return false as false; } ``` - [#&#8203;10678](https://github.com/biomejs/biome/pull/10678) [`8f073a7`](https://github.com/biomejs/biome/commit/8f073a7cd72b4cf46c2ebf2bc08f4068fc4b5e34) Thanks [@&#8203;PranavAchar01](https://github.com/PranavAchar01)! - Fixed [#&#8203;7718](https://github.com/biomejs/biome/issues/7718): Biome now correctly parses CSS nesting selectors when `&` appears as a trailing sub-selector after a type selector, e.g. `h1& { color: red; }`. - [#&#8203;10756](https://github.com/biomejs/biome/pull/10756) [`5ec965a`](https://github.com/biomejs/biome/commit/5ec965a2620dec7cb40aa4946ba1d41408b11fd9) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Fixed CSS formatter output for selector lists with `allowWrongLineComments` and `//` comments after a selector comma. Biome now keeps the selector before the line comment inline instead of breaking it across descendant combinators. ```diff -.powerPathNavigator - .helm - button.pressedButton, // pressed +.powerPathNavigator .helm button.pressedButton, // pressed .powerPathNavigator .helm button:active:not(.disabledButton) { } ``` - [#&#8203;10757](https://github.com/biomejs/biome/pull/10757) [`6232fcd`](https://github.com/biomejs/biome/commit/6232fcdef77471e6a6a74bcc33ff7b2b2a9f85a2) Thanks [@&#8203;PranavAchar01](https://github.com/PranavAchar01)! - Fixed [#&#8203;8269](https://github.com/biomejs/biome/issues/8269): the CSS parser now accepts Tailwind `@variant` and `@utility` names that start with a digit, such as the `2xl` breakpoint. ```css @utility container { @variant 2xl { max-width: 1400px; } } ``` - [#&#8203;10777](https://github.com/biomejs/biome/pull/10777) [`575ced6`](https://github.com/biomejs/biome/commit/575ced6fd7fe3597fdec36e572763e4a5d590244) Thanks [@&#8203;WaterWhisperer](https://github.com/WaterWhisperer)! - Fixed an issue reported in [#&#8203;10708](https://github.com/biomejs/biome/issues/10708): the GitLab reporter now handles `--verbose` diagnostics filtering correctly. - [#&#8203;10281](https://github.com/biomejs/biome/pull/10281) [`0efe244`](https://github.com/biomejs/biome/commit/0efe2442e9b81d83f7332fd792ad6096678f8b2c) Thanks [@&#8203;Zelys-DFKH](https://github.com/Zelys-DFKH)! - Fixed a bug where GritQL patterns rejected positional (unkeyed) arguments. - [#&#8203;10758](https://github.com/biomejs/biome/pull/10758) [`e36fd8a`](https://github.com/biomejs/biome/commit/e36fd8a9f1314744276df515a1137f21802d3aa5) Thanks [@&#8203;henrybrewer00-dotcom](https://github.com/henrybrewer00-dotcom)! - Fixed [#&#8203;10697](https://github.com/biomejs/biome/issues/10697): The formatter no longer removes the parentheses around an `await` or `yield` expression used as the target of a TypeScript instantiation expression. For example, `(await makeFactory)<Value>` is no longer reformatted to `await makeFactory<Value>`, which would change the meaning of the code. - [#&#8203;10586](https://github.com/biomejs/biome/pull/10586) [`3617094`](https://github.com/biomejs/biome/commit/3617094f00e90f7167ff20baf3c12b5014188b35) Thanks [@&#8203;IxxyDev](https://github.com/IxxyDev)! - Fixed [#&#8203;9568](https://github.com/biomejs/biome/issues/9568): [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/) no longer reports a false positive when calling an overloaded function and the selected overload does not return a promise. ```ts function bestEffort(cb: () => Promise<number>): Promise<number>; function bestEffort(cb: () => number): number; function bestEffort( cb: () => number | Promise<number>, ): Promise<number> | number { return cb() as Promise<number> | number; } // This resolves to the second overload, which returns `number`, so it is no // longer flagged as a floating promise. bestEffort(() => 42); ``` - [#&#8203;10766](https://github.com/biomejs/biome/pull/10766) [`7aff4c1`](https://github.com/biomejs/biome/commit/7aff4c11900579a62dc27ef4e02a4c4760fbbff4) Thanks [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562)! - Fixed [#&#8203;2862](https://github.com/biomejs/biome/issues/2862): [`noInteractiveElementToNoninteractiveRole`](https://biomejs.dev/linter/rules/no-interactive-element-to-noninteractive-role/) no longer reports custom elements (a tag name containing a dash, e.g. `<my-button role="img" />`). Per the [W3C HTML-ARIA specification](https://www.w3.org/TR/html-aria/#el-autonomous-custom-element), a custom element may be given any role or none. - [#&#8203;10680](https://github.com/biomejs/biome/pull/10680) [`771daa4`](https://github.com/biomejs/biome/commit/771daa4f7d229a8754f47923f03b899dc0fc5630) Thanks [@&#8203;WaterWhisperer](https://github.com/WaterWhisperer)! - Fixed [#&#8203;10635](https://github.com/biomejs/biome/issues/10635): Biome now recognizes chained table tests such as `test.concurrent.each()` and `it.concurrent.each()` as test calls, fixing `noMisplacedAssertion` false positives and improving formatting for those test declarations. - [#&#8203;10759](https://github.com/biomejs/biome/pull/10759) [`34570b5`](https://github.com/biomejs/biome/commit/34570b5b793c44e978b12589dafcfda22dba7df1) Thanks [@&#8203;henrybrewer00-dotcom](https://github.com/henrybrewer00-dotcom)! - Fixed [#&#8203;10636](https://github.com/biomejs/biome/issues/10636): [noStaticElementInteractions](https://biomejs.dev/linter/rules/no-static-element-interactions/) no longer reports a false positive for event handlers on Svelte special elements such as `<svelte:window>`, `<svelte:document>`, and `<svelte:body>`. These are not real DOM elements, so they are now ignored by the rule. - [#&#8203;10741](https://github.com/biomejs/biome/pull/10741) [`bd2364e`](https://github.com/biomejs/biome/commit/bd2364e3d077e3a77addcab6dbe127db38654e4a) Thanks [@&#8203;JamBalaya56562](https://github.com/JamBalaya56562)! - Fixed [#&#8203;6686](https://github.com/biomejs/biome/issues/6686): the `rage` command now respects the `--config-path` option and the `BIOME_CONFIG_PATH` environment variable when loading the Biome configuration. Previously it always used the default configuration resolution and reported the configuration as `Not set` when no `biome.json` existed in the working directory. - [#&#8203;10763](https://github.com/biomejs/biome/pull/10763) [`2c3e82d`](https://github.com/biomejs/biome/commit/2c3e82d0235ad2f8331744aefc708d1b71f7177c) Thanks [@&#8203;Aqu1bp](https://github.com/Aqu1bp)! - Fixed [#&#8203;10742](https://github.com/biomejs/biome/issues/10742): [`noSolidDestructuredProps`](https://biomejs.dev/linter/rules/no-solid-destructured-props) now reports destructured props in Solid function components and JSX children. - [#&#8203;10606](https://github.com/biomejs/biome/pull/10606) [`a4cc4ab`](https://github.com/biomejs/biome/commit/a4cc4ab0b01a8ef1731d37cb44bccc5522876f2e) Thanks [@&#8203;Mokto](https://github.com/Mokto)! - Fixed false positives in `noUnusedImports`, `noUnusedVariables`, and `useImportType` for Svelte components that use both a `<script module>` and a `<script>` block. The two blocks compile to a single module and share a top-level scope, so a binding (import, function, or variable) declared in one block and used only in the other is no longer reported as unused. - [#&#8203;10767](https://github.com/biomejs/biome/pull/10767) [`36d5aa7`](https://github.com/biomejs/biome/commit/36d5aa77d751bf33485cd2c92d89e4c5764e1e50) Thanks [@&#8203;otkrickey](https://github.com/otkrickey)! - Fixed [#&#8203;10754](https://github.com/biomejs/biome/issues/10754): [`useVueValidVBind`](https://biomejs.dev/linter/rules/use-vue-valid-v-bind/) no longer reports the Vue 3.4+ same-name shorthand as missing a value. `:foo` and `v-bind:foo` are now accepted as equivalent to `:foo="foo"`, while `v-bind`, `v-bind:[dynamicArg]`, and `:[dynamicArg]` without a value continue to be reported. - [#&#8203;10775](https://github.com/biomejs/biome/pull/10775) [`a918af0`](https://github.com/biomejs/biome/commit/a918af0ba827a7fd60a12c96b58daebc8af61db2) Thanks [@&#8203;WaterWhisperer](https://github.com/WaterWhisperer)! - Fixed an issue reported in [#&#8203;10708](https://github.com/biomejs/biome/issues/10708): `biome rage` didn't detect running Biome daemon pipes on Windows. - [#&#8203;10730](https://github.com/biomejs/biome/pull/10730) [`5a2e65b`](https://github.com/biomejs/biome/commit/5a2e65b9929ef0f2294c20e028fd396d760d2b26) Thanks [@&#8203;dinocosta](https://github.com/dinocosta)! - Fixed an issue where Biome was resolving [the well-known Zed settings file](https://biomejs.dev/guides/configure-biome/#well-known-files) from the wrong location on macOS and Windows. - [#&#8203;10807](https://github.com/biomejs/biome/pull/10807) [`d97fffe`](https://github.com/biomejs/biome/commit/d97fffe0aba04cddec66943d6bff3e99d440b451) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed an issue where `.scss` files were incorrectly analyzed when running `biome check`. - [#&#8203;10672](https://github.com/biomejs/biome/pull/10672) [`53c6efc`](https://github.com/biomejs/biome/commit/53c6efcd3e5e2769bf8edbe14b8c06ee9fda52d2) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed a bug where Biome incorrectly formatted snippets that have parsing errors. - [#&#8203;10719](https://github.com/biomejs/biome/pull/10719) [`aa649b5`](https://github.com/biomejs/biome/commit/aa649b586a2221bf058af7ce80af6faa11faf846) Thanks [@&#8203;minseong0324](https://github.com/minseong0324)! - Fixed [`useAwaitThenable`](https://biomejs.dev/linter/rules/use-await-thenable/) false positive when awaiting a custom thenable that is not the global `Promise`. A value with a callable `then` member is now recognized as awaitable. ```ts interface Thenable<T> { then(onfulfilled: (value: T) => void): void; } declare const t: Thenable<number>; async function f() { await t; } ``` - [#&#8203;10734](https://github.com/biomejs/biome/pull/10734) [`4396496`](https://github.com/biomejs/biome/commit/43964961c88ca0f93ee83d10621844fa2dc7515c) Thanks [@&#8203;BangDori](https://github.com/BangDori)! - Fixed [#&#8203;10708](https://github.com/biomejs/biome/issues/10708): `biome migrate` now preserves trivia when migrating the deprecated `recommended` option to `preset`. - [#&#8203;10683](https://github.com/biomejs/biome/pull/10683) [`ae31a00`](https://github.com/biomejs/biome/commit/ae31a004a20ed33d6aa35d5ec8bb4c433273a517) Thanks [@&#8203;Netail](https://github.com/Netail)! - Fixed [#&#8203;10657](https://github.com/biomejs/biome/issues/10657) [#&#8203;10671](https://github.com/biomejs/biome/issues/10671) [#&#8203;10661](https://github.com/biomejs/biome/issues/10661) [#&#8203;10637](https://github.com/biomejs/biome/issues/10637) [#&#8203;10718](https://github.com/biomejs/biome/issues/10718): HTML rules now correctly handle dynamic attributes. - [#&#8203;10746](https://github.com/biomejs/biome/pull/10746) [`54e8239`](https://github.com/biomejs/biome/commit/54e8239bba3f598d7923ac1e446d658714ea7832) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed an issue where [`noUndeclaredClasses`](https://biomejs.dev/linter/rules/no-undeclared-classes) didn't correctly detect styles defined inside the Astro directive `is:global`. - [#&#8203;10770](https://github.com/biomejs/biome/pull/10770) [`dd1429c`](https://github.com/biomejs/biome/commit/dd1429c604f58b89524a3f5329e2920d198e8d9f) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Improved the Biome Language Server DX by orchestrating certain operations, so that they won't block the editor during typing. This improvement is more visible in large documents. - [#&#8203;10473](https://github.com/biomejs/biome/pull/10473) [`d9b5133`](https://github.com/biomejs/biome/commit/d9b5133de7e211b22f4531fe220070690a18c8d1) Thanks [@&#8203;Mokto](https://github.com/Mokto)! - Improved [`noUnusedImports`](https://biomejs.dev/linter/rules/no-unused-imports/), [`noUnusedVariables`](https://biomejs.dev/linter/rules/no-unused-variables/), [`noUnusedFunctionParameters`](https://biomejs.dev/linter/rules/no-unused-function-parameters/), and [`useImportType`](https://biomejs.dev/linter/rules/use-import-type/) for Svelte, Vue, and Astro files (with `html.experimentalFullSupportEnabled`). Bindings used only in the template — including component tags, attribute interpolations, directives, `bind:` shorthand, and snippet parameters — are no longer reported as unused, while genuinely unused ones still are. - [#&#8203;10796](https://github.com/biomejs/biome/pull/10796) [`f1b3ab2`](https://github.com/biomejs/biome/commit/f1b3ab2c09522a52c93f669ce679675237b96813) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed an issue where the Biome Language Server didn't enable project or type-aware lint rules, even when they were explicitly enabled. - [#&#8203;10746](https://github.com/biomejs/biome/pull/10746) [`54e8239`](https://github.com/biomejs/biome/commit/54e8239bba3f598d7923ac1e446d658714ea7832) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed an issue where [`noUndeclaredClasses`](https://biomejs.dev/linter/rules/no-undeclared-classes) didn't detect styles declared inside HTML documents. - [#&#8203;10774](https://github.com/biomejs/biome/pull/10774) [`bde945b`](https://github.com/biomejs/biome/commit/bde945bee29cb566086828ad788153d9111a125a) Thanks [@&#8203;pattrickrice](https://github.com/pattrickrice)! - Fixed [#&#8203;10268](https://github.com/biomejs/biome/issues/10268) where a race condition resulted in internal errors such as: `The file biome.json does not exist in the workspace`. ### [`v2.5.1`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#2513) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.5.0...@biomejs/biome@2.5.1) ##### Patch Changes - [#&#8203;11379](https://github.com/biomejs/biome/pull/11379) [`07a0073`](https://github.com/biomejs/biome/commit/07a0073c1e1b1de323292968b8988cc6f79ec5c7) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the nursery rule [`useLayeredStyles`](https://biomejs.dev/linter/rules/use-layered-styles/), which enforces that style rules are defined within a cascade layer and import rules to import its styles into a cascade layer. ```css /* Invalid */ @import 'foo.css'; .my-style { color: red; } /* Valid */ @import 'foo.css' layer(base); @layer base { .my-style { color: red; } } ``` - [#&#8203;11667](https://github.com/biomejs/biome/pull/11667) [`e997900`](https://github.com/biomejs/biome/commit/e997900c3eaf9d5efaf1ca12a067a962e1a04d0b) Thanks [@&#8203;devtechedge](https://github.com/devtechedge)! - Added the nursery rule [`useBetterDomTraversing`](https://biomejs.dev/linter/rules/use-better-dom-traversing), which prefers `.firstChild`, `.firstElementChild`, `.closest()`, and merged `.querySelector()` calls over positional DOM traversal. ```js element.childNodes[0]; element.children[0]; element.parentElement.parentElement; element.querySelector("a").querySelector("b"); ``` - [#&#8203;11620](https://github.com/biomejs/biome/pull/11620) [`20e513a`](https://github.com/biomejs/biome/commit/20e513af6fb0127854f4eb5cb9edee0f20d1b543) Thanks [@&#8203;jakeleventhal](https://github.com/jakeleventhal)! - Fixed [#&#8203;11610](https://github.com/biomejs/biome/issues/11610), [#&#8203;11611](https://github.com/biomejs/biome/issues/11611), [#&#8203;11612](https://github.com/biomejs/biome/issues/11612), [#&#8203;11615](https://github.com/biomejs/biome/issues/11615), and [#&#8203;11616](https://github.com/biomejs/biome/issues/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`](https://biomejs.dev/linter/rules/use-regexp-exec), [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises), [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises), [`useNullishCoalescing`](https://biomejs.dev/linter/rules/use-nullish-coalescing), and [`noUnsafePlusOperands`](https://biomejs.dev/linter/rules/no-unsafe-plus-operands). - [#&#8203;11657](https://github.com/biomejs/biome/pull/11657) [`e322040`](https://github.com/biomejs/biome/commit/e32204014687469e6c6f3684d32caf56311cc118) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;7495](https://github.com/biomejs/biome/issues/7495): [`noUselessConstructor`](https://biomejs.dev/linter/rules/no-useless-constructor/) 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. - [#&#8203;11670](https://github.com/biomejs/biome/pull/11670) [`4969ee1`](https://github.com/biomejs/biome/commit/4969ee1d73b48615f46f024539cfdb847f07064d) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;7076](https://github.com/biomejs/biome/issues/7076): [`useAriaPropsForRole`](https://biomejs.dev/linter/rules/use-aria-props-for-role) and [`useFocusableInteractive`](https://biomejs.dev/linter/rules/use-focusable-interactive) no longer report non-focusable elements with `role="separator"`. A separator with an explicit `tabIndex` or `tabindex` still requires `aria-valuenow`. - [#&#8203;11627](https://github.com/biomejs/biome/pull/11627) [`23aad6d`](https://github.com/biomejs/biome/commit/23aad6df8f71bd9b134633c43d2334771687d10d) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;6571](https://github.com/biomejs/biome/issues/6571) so Grit plugins can capture and inspect multiple named import specifiers. - [#&#8203;11631](https://github.com/biomejs/biome/pull/11631) [`00dbd3a`](https://github.com/biomejs/biome/commit/00dbd3a30489617d5bb55466006ac9977612a23b) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - 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. - [#&#8203;11628](https://github.com/biomejs/biome/pull/11628) [`a2f8ff7`](https://github.com/biomejs/biome/commit/a2f8ff7a1eb01f5c91e7154937e17f761863e3bc) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery rule [`noXorAsExponentiation`](https://biomejs.dev/linter/rules/no-xor-as-exponentiation/), which reports the bitwise XOR operator `^` between two decimal integer literals, where the exponentiation operator `**` was likely intended. ```js const kibibyte = 2 ^ 10; // 8, not 1024 ``` - [#&#8203;11670](https://github.com/biomejs/biome/pull/11670) [`4969ee1`](https://github.com/biomejs/biome/commit/4969ee1d73b48615f46f024539cfdb847f07064d) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;7192](https://github.com/biomejs/biome/issues/7192): [`noUnusedPrivateClassMembers`](https://biomejs.dev/linter/rules/no-unused-private-class-members/) now considers compound assignments such as `??=` to read and use private class members. - [#&#8203;11676](https://github.com/biomejs/biome/pull/11676) [`840a52a`](https://github.com/biomejs/biome/commit/840a52ad14b027e21661a9121b316ccac139d736) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;11672](https://github.com/biomejs/biome/issues/11672) and [#&#8203;11671](https://github.com/biomejs/biome/issues/11671) by disabling the experimental capitalized-call and effect-dependency checks in [`useReactCompiler`](https://biomejs.dev/linter/rules/use-react-compiler/), 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. - [#&#8203;11660](https://github.com/biomejs/biome/pull/11660) [`49485ed`](https://github.com/biomejs/biome/commit/49485eda65813e5b7e2be68cdd56ffd90674f713) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;11653](https://github.com/biomejs/biome/issues/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. - [#&#8203;11664](https://github.com/biomejs/biome/pull/11664) [`9a73b9c`](https://github.com/biomejs/biome/commit/9a73b9cc4bb1000336dc25704546f4d63a9bb326) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Improved the performance of [`useRegexpExec`](https://biomejs.dev/linter/rules/use-regexp-exec/). - [#&#8203;11661](https://github.com/biomejs/biome/pull/11661) [`5341b3f`](https://github.com/biomejs/biome/commit/5341b3fb9c7bae8ce2426d32e6e72aed9637a82f) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;7479](https://github.com/biomejs/biome/issues/7479). [`noUnusedVariables`](https://biomejs.dev/linter/rules/no-unused-variables/) now treats Unicode escapes in identifiers as the same binding as their decoded spelling. - [#&#8203;11630](https://github.com/biomejs/biome/pull/11630) [`62e1fc5`](https://github.com/biomejs/biome/commit/62e1fc59621b6ab5c3988ae36b6591180e07d08f) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed the HTML formatter inserting whitespace between adjacent Svelte expressions when their combined length exceeds the line width. ```diff <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> ``` - [#&#8203;11658](https://github.com/biomejs/biome/pull/11658) [`ed4bfa4`](https://github.com/biomejs/biome/commit/ed4bfa4a1de63241a7c3586ff12d7f990cf84303) Thanks [@&#8203;fredrikblau](https://github.com/fredrikblau)! - Fixed [#&#8203;11644](https://github.com/biomejs/biome/issues/11644): [`useHeadingContent`](https://biomejs.dev/linter/rules/use-heading-content/) no longer reports headings that render their text with a directive: `set:html` and `set:text` in Astro files, `v-html` and `v-text` in Vue files. ```astro <h1 set:html={heading} /> <h2 set:text={heading}></h2> ``` ```vue <template> <h1 v-html="heading"></h1> <h2 v-text="heading"></h2> </template> ``` - [#&#8203;11613](https://github.com/biomejs/biome/pull/11613) [`47d7383`](https://github.com/biomejs/biome/commit/47d7383d049b36ff8eaba50912176928143dd9e9) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Improved the performance of Biome Formatter up to \~50% in some cases. - [#&#8203;11655](https://github.com/biomejs/biome/pull/11655) [`fd8fc74`](https://github.com/biomejs/biome/commit/fd8fc741ee2b77b3b127859fabc7a29b19e1fb0b) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;6974](https://github.com/biomejs/biome/issues/6974), where [`noUnusedPrivateClassMembers`](https://biomejs.dev/linter/rules/no-unused-private-class-members/) incorrectly reported TypeScript private constructor properties read through object destructuring from `this` as unused. - [#&#8203;11618](https://github.com/biomejs/biome/pull/11618) [`21a10cf`](https://github.com/biomejs/biome/commit/21a10cfcac4db8044e8bff6b24d9b1e197c2b343) Thanks [@&#8203;siketyan](https://github.com/siketyan)! - Fixed [#&#8203;11605](https://github.com/biomejs/biome/issues/11605): Type inference now infers the type of an unannotated callback parameter from the signature of the function the callback is passed to, and honours explicit type arguments on call expressions. This improves type-aware analysis for [`noBaseToString`](https://biomejs.dev/linter/rules/no-base-to-string/), [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/), [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/), [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises/), [`noUnnecessaryConditions`](https://biomejs.dev/linter/rules/no-unnecessary-conditions/), [`noUnsafePlusOperands`](https://biomejs.dev/linter/rules/no-unsafe-plus-operands/), [`noUselessTypeConversion`](https://biomejs.dev/linter/rules/no-useless-type-conversion/), [`useArrayFind`](https://biomejs.dev/linter/rules/use-array-find/), [`useArraySortCompare`](https://biomejs.dev/linter/rules/use-array-sort-compare/), [`useAwaitThenable`](https://biomejs.dev/linter/rules/use-await-thenable/), [`useDisposables`](https://biomejs.dev/linter/rules/use-disposables/), [`useExhaustiveSwitchCases`](https://biomejs.dev/linter/rules/use-exhaustive-switch-cases/), [`useIncludes`](https://biomejs.dev/linter/rules/use-includes/), [`useNullishCoalescing`](https://biomejs.dev/linter/rules/use-nullish-coalescing/), [`useRegexpExec`](https://biomejs.dev/linter/rules/use-regexp-exec/), and [`useStringStartsEndsWith`](https://biomejs.dev/linter/rules/use-string-starts-ends-with/). For example, `noFloatingPromises` can now detect Promises reached through such parameters: ```ts interface Context { doSomething(): Promise<void>; } declare function test(callback: (ctx: Context) => Promise<void>): void; test(async (ctx) => { ctx.doSomething(); // now reported as a floating promise }); ``` - [#&#8203;11698](https://github.com/biomejs/biome/pull/11698) [`b019982`](https://github.com/biomejs/biome/commit/b019982bfbf8a9db58bd16b1e5e1a241128540d4) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Fixed parsing of unquoted CSS URLs beginning with `@` or `!`, such as `url(@/assets/icon.svg)` and `url(!font.woff2)`. Preserved escaped and non-ASCII whitespace in raw URLs during formatting. ```diff -background-image: url(image\); +background-image: url(image\ ); ``` - [#&#8203;11622](https://github.com/biomejs/biome/pull/11622) [`c23e4c7`](https://github.com/biomejs/biome/commit/c23e4c7e7a33d3f00863d80be663678af8c2a073) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the nursery rule [`noUnsafeIframeSandbox`](https://biomejs.dev/linter/rules/no-unsafe-iframe-sandbox/), which reports `iframe` elements whose `sandbox` attribute combines `allow-scripts` and `allow-same-origin`, since that combination lets the embedded document remove its own sandboxing. ```jsx <iframe src="https://example.com" sandbox="allow-scripts allow-same-origin" /> ``` - [#&#8203;11606](https://github.com/biomejs/biome/pull/11606) [`de0528f`](https://github.com/biomejs/biome/commit/de0528f940ea41b798816e1923b2b51ffcd0b473) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the recommended [`noSvelteAtHtmlTags`](https://biomejs.dev/linter/rules/no-svelte-at-html-tags) nursery rule, which reports Svelte `{@html}` tags that render unescaped HTML. - [#&#8203;11670](https://github.com/biomejs/biome/pull/11670) [`4969ee1`](https://github.com/biomejs/biome/commit/4969ee1d73b48615f46f024539cfdb847f07064d) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;6782](https://github.com/biomejs/biome/issues/6782): GritQL plugins now match captured JSX component names against code snippets such as `React.Fragment`. - [#&#8203;11687](https://github.com/biomejs/biome/pull/11687) [`09d97d9`](https://github.com/biomejs/biome/commit/09d97d973b522c6bd95e6d26006cb4b3a221396d) Thanks [@&#8203;hori-design](https://github.com/hori-design)! - Fixed [#&#8203;11678](https://github.com/biomejs/biome/issues/11678): [`useReactCompiler`](https://biomejs.dev/linter/rules/use-react-compiler/) no longer panics on files that contain non-ASCII characters. This bumps the React Compiler version. - [#&#8203;11595](https://github.com/biomejs/biome/pull/11595) [`a64d757`](https://github.com/biomejs/biome/commit/a64d7572d5684f3555be5dc02eb1d29a16f290dc) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the nursery Vue-domain rule [`useVueBaseImport`](https://biomejs.dev/linter/rules/use-vue-base-import/) rule, which enforces importing Vue APIs from `vue` instead of internal `@vue/*` packages. - [#&#8203;11675](https://github.com/biomejs/biome/pull/11675) [`353cbae`](https://github.com/biomejs/biome/commit/353cbae47056f8e03b27d1d9b69e165b5b72f122) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [`useReactCompiler`](https://biomejs.dev/linter/rules/use-react-compiler/) silently producing no diagnostics in WebAssembly builds, including the playground. - [#&#8203;11625](https://github.com/biomejs/biome/pull/11625) [`ea20e5a`](https://github.com/biomejs/biome/commit/ea20e5a4640b4455cd12e0eb6ffaa590803c67a2) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Improved linting performance for large CSS and JSON files. - [#&#8203;11670](https://github.com/biomejs/biome/pull/11670) [`4969ee1`](https://github.com/biomejs/biome/commit/4969ee1d73b48615f46f024539cfdb847f07064d) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;7527](https://github.com/biomejs/biome/issues/7527): suppression actions for diagnostics emitted on comments are now inserted before the diagnostic comment. In particular, suppressing [`noTsIgnore`](https://biomejs.dev/linter/rules/no-ts-ignore/) now places the `biome-ignore` comment before `@ts-ignore`. - [#&#8203;11655](https://github.com/biomejs/biome/pull/11655) [`fd8fc74`](https://github.com/biomejs/biome/commit/fd8fc741ee2b77b3b127859fabc7a29b19e1fb0b) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;8629](https://github.com/biomejs/biome/issues/8629), where [`noUnusedPrivateClassMembers`](https://biomejs.dev/linter/rules/no-unused-private-class-members/) incorrectly reported used private TypeScript method overload signatures as unused. - [#&#8203;11669](https://github.com/biomejs/biome/pull/11669) [`579f401`](https://github.com/biomejs/biome/commit/579f401b0a97760db99d64b97b2bc29ab20e3f8a) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Improved the performance of [`noExcessiveLinesPerFile`](https://biomejs.dev/linter/rules/no-excessive-lines-per-file/) when `skipBlankLines` is `false`. ### [`v2.5.0`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#250) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.16...@biomejs/biome@2.5.0) ##### Minor Changes - [#&#8203;9539](https://github.com/biomejs/biome/pull/9539) [`f0615fd`](https://github.com/biomejs/biome/commit/f0615fdae80fa7257fc1d0448d2027cb1acff46e) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Added a new reporter called `concise`. When `--reporter=concise` is passed the commands `format`, `lint`, `check` and `ci`, the diagnostics are printed in a compact manner: ``` ! index.ts:2:10: lint/correctness/noUnusedImports: Several of these imports are unused. ! main.ts:9:7: lint/correctness/noUnusedVariables: This variable f is unused. × index.ts:8:5: lint/suspicious/noImplicitAnyLet: This variable implicitly has the any type. × main.ts:2:10: lint/suspicious/noRedeclare: Shouldn't redeclare 'z'. Consider to delete it or rename it. ``` - [#&#8203;9495](https://github.com/biomejs/biome/pull/9495) [`2056b23`](https://github.com/biomejs/biome/commit/2056b23812a17f9c9a9015e5b725faecb04647b5) Thanks [@&#8203;aviraldua93](https://github.com/aviraldua93)! - Added the [`useKeyWithClickEvents`](https://biomejs.dev/linter/rules/use-key-with-click-events/) a11y lint rule for HTML files (`.html`, `.vue`, `.svelte`, `.astro`). This is a port of the existing JSX rule. The rule enforces that elements with an `onclick` handler also have at least one keyboard event handler (`onkeydown`, `onkeyup`, or `onkeypress`) to ensure keyboard accessibility. Inherently keyboard-accessible elements (`<a>`, `<button>`, `<input>`, `<select>`, `<textarea>`, `<option>`) are excluded, as are elements hidden from assistive technologies (`aria-hidden`) or with `role="presentation"` / `role="none"`. ```html <!-- Invalid: no keyboard handler --> <div onclick="handleClick()">Click me</div> <!-- Valid: has keyboard handler --> <div onclick="handleClick()" onkeydown="handleKeyDown()">Click me</div> <!-- Valid: inherently keyboard-accessible --> <button onclick="handleClick()">Submit</button> ``` - [#&#8203;9152](https://github.com/biomejs/biome/pull/9152) [`9ec8500`](https://github.com/biomejs/biome/commit/9ec8500dabc7305cbe04ecf27a84a1450f012c0b) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Added new nursery lint rule [`noUndeclaredClasses`](https://biomejs.dev/linter/rules/no-undeclared-classes/) for HTML, JSX, and SFC files (Vue, Astro, Svelte). The rule detects CSS class names used in `class="..."` (or `className`) attributes that are not defined in any `<style>` block or linked stylesheet reachable from the file. ```html <!-- .typo is used but never defined --> <html> <head> <style> .button { color: blue; } </style> </head> <body> <div class="button typo"></div> </body> </html> ``` - [#&#8203;9152](https://github.com/biomejs/biome/pull/9152) [`9ec8500`](https://github.com/biomejs/biome/commit/9ec8500dabc7305cbe04ecf27a84a1450f012c0b) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Added new nursery lint rule [`noUnusedClasses`](https://biomejs.dev/linter/rules/no-unused-classes/) for CSS. The rule detects CSS class selectors that are never referenced in any HTML or JSX file that imports the stylesheet. This is a project-domain rule that requires the module graph. ```css /* styles.css — .ghost is never used in any importing file */ .button { color: blue; } .ghost { color: red; } ``` ```jsx /* App.jsx */ import "./styles.css"; export default () => <div className="button" />; ``` - [#&#8203;9546](https://github.com/biomejs/biome/pull/9546) [`6567efa`](https://github.com/biomejs/biome/commit/6567efa51ba074436b017e49b1d2d369e7252e74) Thanks [@&#8203;nhedger](https://github.com/nhedger)! - Added a `biome upgrade` command for standalone installations. It upgrades Homebrew installs with `brew upgrade biome`, updates manually installed binaries from the latest GitHub release, and tells npm users to upgrade with their package manager instead. - [#&#8203;9716](https://github.com/biomejs/biome/pull/9716) [`701767a`](https://github.com/biomejs/biome/commit/701767a3c4de8bce032933588ef2b6e5e252919f) Thanks [@&#8203;faizkhairi](https://github.com/faizkhairi)! - Added the HTML version of the [`useHeadingContent`](https://biomejs.dev/linter/rules/use-heading-content/) rule. The rule now enforces that heading elements (`h1`-`h6`) have content accessible to screen readers in HTML, Vue, Svelte, and Astro files. ```html <!-- Invalid: empty heading --> <h1></h1> <!-- Invalid: heading hidden from screen readers --> <h1 aria-hidden="true">invisible content</h1> <!-- Valid: heading with text content --> <h1>heading</h1> <!-- Valid: heading with accessible name --> <h1 aria-label="Screen reader content"></h1> ``` - [#&#8203;9582](https://github.com/biomejs/biome/pull/9582) [`f437ef8`](https://github.com/biomejs/biome/commit/f437ef8b6b0eb8f909d523950cf2c543042083d5) Thanks [@&#8203;rahuld109](https://github.com/rahuld109)! - Added the HTML version of the [`useKeyWithMouseEvents`](https://biomejs.dev/linter/rules/use-key-with-mouse-events/) rule. The rule now enforces that `onmouseover` is accompanied by `onfocus` and `onmouseout` is accompanied by `onblur` in HTML, Vue, Svelte, and Astro files. ```html <!-- Invalid: onmouseover without onfocus --> <div onmouseover="handleMouseOver()"></div> <!-- Valid: onmouseover paired with onfocus --> <div onmouseover="handleMouseOver()" onfocus="handleFocus()"></div> ``` - [#&#8203;9275](https://github.com/biomejs/biome/pull/9275) [`1fdbcee`](https://github.com/biomejs/biome/commit/1fdbceea62d373f24da9c1e5cc0cdd169b573e84) Thanks [@&#8203;ff1451](https://github.com/ff1451)! - Added the new assist action [`useSortedTypeFields`](https://biomejs.dev/assist/actions/use-sorted-type-fields/), which sorts the fields of GraphQL object types, interface types and input object types alphabetically, e.g. `name, age, id` becomes `age, id, name`. - [#&#8203;10561](https://github.com/biomejs/biome/pull/10561) [`78075b7`](https://github.com/biomejs/biome/commit/78075b7c7cb7490c730a96f4ee9776c9e77826e7) Thanks [@&#8203;Conaclos](https://github.com/Conaclos)! - Added a new `style` option to [useExportType](https://biomejs.dev/linter/rules/use-export-type/), which enforces a style for exporting types. This is the same option as the one provided by `useImportType`. - [#&#8203;8987](https://github.com/biomejs/biome/pull/8987) [`d16e32b`](https://github.com/biomejs/biome/commit/d16e32b5b971a4ed9cd3bf5098782c8b752af69a) Thanks [@&#8203;DerTimonius](https://github.com/DerTimonius)! - Ported the [`useValidAnchor`](https://biomejs.dev/linter/rules/use-valid-anchor/) rule to HTML. This rule enforces that all anchors are valid and that they are navigable elements. - [#&#8203;9533](https://github.com/biomejs/biome/pull/9533) [`4d251d4`](https://github.com/biomejs/biome/commit/4d251d489cfd33a83e42d425476f8d6c66b72d9b) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - The `init` command now prints the Biome logo. - [#&#8203;10069](https://github.com/biomejs/biome/pull/10069) [`0eb9310`](https://github.com/biomejs/biome/commit/0eb93109e1f9bfbb20744961681b4f0b9b781ad5) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the HTML lint rule [`noStaticElementInteractions`](https://biomejs.dev/linter/rules/no-static-element-interactions/), which enforces that static, visible elements (such as `<div>`) that have click handlers use the valid role attribute. **Invalid**: ```html <div onclick="myFunction()"></div> ``` - [#&#8203;9134](https://github.com/biomejs/biome/pull/9134) [`2a43488`](https://github.com/biomejs/biome/commit/2a434882746d31e1bd3c8e0d711372a539ce88f8) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Added the assist action [`useSortedPackageJson`](https://biomejs.dev/assist/actions/use-sorted-package-json). This action organizes package.json fields according to the same conventions as the popular [sort-package-json](https://github.com/keithamus/sort-package-json) tool. - [#&#8203;9309](https://github.com/biomejs/biome/pull/9309) [`7daa18b`](https://github.com/biomejs/biome/commit/7daa18b07f7ab348942f4cb83b475e6a4b3d1125) Thanks [@&#8203;Bertie690](https://github.com/Bertie690)! - The `allowDoubleNegation` option has been added to [`noImplicitCoercions`](https://biomejs.dev/linter/rules/no-implicit-coercions) to allow ignoring double negations inside code. With the option enabled, the following example is considered valid and is ignored by the rule: ```js const truthy = !!value; ``` - [#&#8203;9700](https://github.com/biomejs/biome/pull/9700) [`894f3fb`](https://github.com/biomejs/biome/commit/894f3fb4c664b12ff9abd1527b535621fe4e22f6) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - The Biome Language server now supports the "go-to definition" feature. When the cursor of the mouse is hovering an entity (variable, CSS class, type, etc.), and the command <kbd>CTRL</kbd> + click is triggered, the editor jumps to where this entity is defined, if the language server can find it. Here's what Biome is able to resolve: - Variables and types used in JavaScript modules, defined in the same file or imported from another module. - JSX Components used in JavaScript modules, defined in the same file or imported from another module. - CSS classes used in JSX and HTML-ish files (Vue, Svelte and Astro), and defined in CSS files. - Components used in HTML-ish files and defined in other HTML-ish. - Variables used in HTML-ish files and defined in the same file or imported from another module (JavaScript or HTML-ish). - [#&#8203;10070](https://github.com/biomejs/biome/pull/10070) [`bae0710`](https://github.com/biomejs/biome/commit/bae071050f5a9c335b4483ee384f21ac1e6f0b4d) Thanks [@&#8203;Conaclos](https://github.com/Conaclos)! - Added the `:STYLE:` group matcher for [`organizeImports`](https://biomejs.dev/assist/actions/organize-imports/) that matches style imports. For example, the following configuration... ```json { "assist": { "actions": { "source": { "organizeImports": { "level": "on", "options": { "groups": ["**", "!:STYLE:"], "sortBareImports": true } } } } } } ``` ...places style imports last: ```diff - import "./style.css" import A from "./a.js" + import "./style.css" ``` - [#&#8203;9170](https://github.com/biomejs/biome/pull/9170) [`e3107de`](https://github.com/biomejs/biome/commit/e3107deedcff0f02b61702c6645d89e8d8635b49) Thanks [@&#8203;mdrobny](https://github.com/mdrobny)! - Added `bundleDependencies` option to [NoUndeclaredDependencies](https://biomejs.dev/linter/rules/no-undeclared-dependencies) rule. This rule now supports imports of packages that are defined only in `bundleDependencies` and `bundledDependencies` arrays. - [#&#8203;9547](https://github.com/biomejs/biome/pull/9547) [`01f8473`](https://github.com/biomejs/biome/commit/01f847317820f805698e1b8ba9eaa8fa6c26205c) Thanks [@&#8203;mujpao](https://github.com/mujpao)! - Added new assist rule [`useSortedAttributes`](https://biomejs.dev/assist/actions/use-sorted-attributes/) for HTML, porting the existing JSX rule. This rule enforces sorted HTML attributes. **Invalid** ```html <input type="text" id="name" name="name" /> ``` - [#&#8203;9366](https://github.com/biomejs/biome/pull/9366) [`2ca1117`](https://github.com/biomejs/biome/commit/2ca1117f1e63f6cd99c0ce8d4b82475625838e2e) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added the `html.parser.vue` configuration option. When enabled, it adds support for the parsing of Vue in `.html` files. Most Vue users don't need to enable this option since Vue files typically use the `.vue` extension, but it can be useful for projects that embed Vue syntax in regular HTML files. - [#&#8203;9073](https://github.com/biomejs/biome/pull/9073) [`74b20ee`](https://github.com/biomejs/biome/commit/74b20eee556c9acc72ad5ea335b1bf0983d2eb2e) Thanks [@&#8203;chocky335](https://github.com/chocky335)! - Added support for applying GritQL plugin rewrites as code actions. GritQL plugins that use the rewrite operator (`=>`) now produce fixable diagnostics for JavaScript, CSS, and JSON files. By default, plugin rewrites are treated as unsafe fixes and require `--write --unsafe` to apply. Plugin authors can pass `fix_kind = "safe"` to `register_diagnostic()` to mark a fix as safe, allowing it to be applied with just `--write`. **Example plugin** (`useConsoleInfo.grit`): ```grit language js `console.log($msg)` as $call where { register_diagnostic(span = $call, message = "Use console.info instead of console.log.", severity = "warn", fix_kind = "safe"), $call => `console.info($msg)` } ``` Running `biome check --write` applies safe rewrites. Unsafe rewrites (the default, or `fix_kind = "unsafe"`) still require `--write --unsafe`. - [#&#8203;9384](https://github.com/biomejs/biome/pull/9384) [`f4c9edc`](https://github.com/biomejs/biome/commit/f4c9edca8f8772a1e65d9e6701fdc3f604a9f3fe) Thanks [@&#8203;Conaclos](https://github.com/Conaclos)! - Added the `sortBareImports` option to [`organizeImports`](https://biomejs.dev/assist/actions/organize-imports/), which allows bare imports to be sorted within other imports when set to `false`. ```json { "assist": { "actions": { "source": { "organizeImports": { "level": "on", "options": { "sortBareImports": true } } } } } } ``` ```diff - import "b"; import "a"; + import "b"; import { A } from "a"; + import "./file"; import { Local } from "./file"; - import "./file"; ``` - [#&#8203;8731](https://github.com/biomejs/biome/pull/8731) [`e7872bf`](https://github.com/biomejs/biome/commit/e7872bffba88f60d6c3cb6d0c2dd7a25452a0205) Thanks [@&#8203;siketyan](https://github.com/siketyan)! - Added the watch mode (`--watch`) to the CLI for `check`/`format`/`lint` commands. By enabling this option, Biome will re-run the check automatically when any file in the workspace has changed after the first run. - [#&#8203;10106](https://github.com/biomejs/biome/pull/10106) [`9b35f78`](https://github.com/biomejs/biome/commit/9b35f78e183edf44a3d8b7077ebb0c548a7e92f5) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Biome can now format and lint `.svg` files. - [#&#8203;9967](https://github.com/biomejs/biome/pull/9967) [`e9b6c17`](https://github.com/biomejs/biome/commit/e9b6c17cd6f7e870aea68da3b6c6474aa1a9b4f6) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added HTML support for [`noExcessiveLinesPerFile`](https://biomejs.dev/linter/rules/no-excessive-lines-per-file/). Biome now reports HTML files that exceed the configured line limit, including when `skipBlankLines` is enabled. - [#&#8203;9491](https://github.com/biomejs/biome/pull/9491) [`b3eb63c`](https://github.com/biomejs/biome/commit/b3eb63c7e19e6ebd41e463289de098bb003686e1) Thanks [@&#8203;IxxyDev](https://github.com/IxxyDev)! - Added the HTML lint rule [`noAriaUnsupportedElements`](https://biomejs.dev/linter/rules/no-aria-unsupported-elements/). This rule enforces that elements that do not support ARIA roles, states, and properties (`meta`, `html`, `script`, `style`) do not have `role` or `aria-*` attributes. ```html <!-- Invalid: meta does not support aria attributes --> <meta charset="UTF-8" role="meta" /> ``` - [#&#8203;9306](https://github.com/biomejs/biome/pull/9306) [`afd57a6`](https://github.com/biomejs/biome/commit/afd57a634bdb6b0b161dc8a2522ac460503569b1) Thanks [@&#8203;viraxslot](https://github.com/viraxslot)! - Added the [`noNoninteractiveTabindex`](https://biomejs.dev/linter/rules/no-noninteractive-tabindex/) lint rule for HTML. This rule enforces that `tabindex` is not used on non-interactive elements, as it can cause usability issues for keyboard users. ```html <div tabindex="0">Invalid: non-interactive element</div> ` ``` - [#&#8203;9276](https://github.com/biomejs/biome/pull/9276) [`6d041d9`](https://github.com/biomejs/biome/commit/6d041d919e06595553093e084e6aad0d39fb8109) Thanks [@&#8203;IxxyDev](https://github.com/IxxyDev)! - Added the HTML lint rule [`noRedundantRoles`](https://biomejs.dev/linter/rules/no-redundant-roles/). This rule enforces that explicit `role` attributes are not the same as the implicit/default role of an HTML element. It supports HTML, Vue, Svelte, and Astro files. ```html <!-- Invalid: role="button" is redundant on <button> --> <button role="button"></button> ``` - [#&#8203;9813](https://github.com/biomejs/biome/pull/9813) [`69aadc2`](https://github.com/biomejs/biome/commit/69aadc27741bb8a74c926e14a2a9777064cb1e03) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Added a new linter configuration called `preset`. With the new option, users can enable different kinds of rules at once. The following presets are available: - `"recommended"`: it enables all Biome-recommended rules, or recommended rules of a group; - `"all"`: it enables all Biome rules, or enables all rules of a group; - `"none"`: it disables all Biome rules, or disable all rules of a group. You can enable recommended rules: ```json { "linter": { "rules": { "preset": "recommended" } } } ``` You can enable **all rules** at once: ```json5 { linter: { rules: { preset: "all", // enables all rules }, }, } ``` Or enable all rules for a group: ```json5 { linter: { rules: { style: { preset: "all", // enables all rules in the style group }, }, }, } ``` This new option, however, doesn't affect how nursery rules work. Nursery rules must be enabled singularly, due to their nature. This new option is meant to replace `recommended`, so make sure to run the `migrate` command. - [#&#8203;10022](https://github.com/biomejs/biome/pull/10022) [`3422d71`](https://github.com/biomejs/biome/commit/3422d71bc5e9d7f07fd4e7509566427e1591d760) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the HTML lint rule [`noNoninteractiveElementToInteractiveRole`](https://biomejs.dev/linter/rules/no-noninteractive-element-to-interactive-role/), which enforces that interactive ARIA roles are not assigned to non-interactive HTML elements. **Invalid**: ```html <h1 role="checkbox"></h1> ``` - [#&#8203;8396](https://github.com/biomejs/biome/pull/8396) [`13785fc`](https://github.com/biomejs/biome/commit/13785fc8f4be068eccff84a8ad90ac8530d5c992) Thanks [@&#8203;apple-yagi](https://github.com/apple-yagi)! - Biome now supports pnpm catalogs (default and named) when resolving dependencies for linting. This behavior is opt-in and requires setting `javascript.resolver.experimentalPnpmCatalogs` to `true`. - [#&#8203;10028](https://github.com/biomejs/biome/pull/10028) [`1009414`](https://github.com/biomejs/biome/commit/100941409f3ec5e6653e92b2cfbb4100df1becb0) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the HTML lint rule [`noInteractiveElementToNoninteractiveRole`](https://biomejs.dev/linter/rules/no-interactive-element-to-noninteractive-role/), which enforces that non-interactive ARIA roles are not assigned to interactive HTML elements. **Invalid**: ```html <input role="img" /> ``` - [#&#8203;9853](https://github.com/biomejs/biome/pull/9853) [`816302f`](https://github.com/biomejs/biome/commit/816302f8c8c9862585c283fce22ffd1817dedf9f) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the new assist action [`useSortedSelectionSet`](https://biomejs.dev/assist/actions/use-sorted-selection-set/), which sorts GraphQL selection sets alphabetically, e.g. `name, age, id` becomes `age, id, name`. **Invalid**: ```graphql query { name age id } ``` - [#&#8203;10074](https://github.com/biomejs/biome/pull/10074) [`9c7c6eb`](https://github.com/biomejs/biome/commit/9c7c6eb99f6880aa87ae0e7aff357e978361c4a3) Thanks [@&#8203;georgephillips](https://github.com/georgephillips)! - Added a `kind` field to the `ImportMatcher` used by the [`organizeImports`](https://biomejs.dev/assist/actions/organize-imports/) assist action. The new field selects imports by their syntactic kind and currently supports `bare` (matching side-effect imports such as `import "polyfill"`) with optional `!` negation (`!bare`). The matcher composes with the existing `type` and `source` fields, so users can express patterns such as "only bare imports that import a CSS file" (`{ "kind": "bare", "source": "**/*.css" }`). For example, with the following configuration: ```json { "assist": { "actions": { "source": { "organizeImports": { "level": "on", "options": { "sortBareImports": true, "groups": [ { "kind": "!bare" }, ":BLANK_LINE:", { "kind": "bare" } ] } } } } } } ``` ...the following code: ```ts import "./register-my-component"; import { render } from "react-dom"; import "./polyfill"; import { Button } from "@/components/Button"; ``` ...is organized as: ```ts import { render } from "react-dom"; import { Button } from "@/components/Button"; import "./polyfill"; import "./register-my-component"; ``` - [#&#8203;9171](https://github.com/biomejs/biome/pull/9171) [`ce65710`](https://github.com/biomejs/biome/commit/ce65710f591eb2676df6833e9cd00e310981692b) Thanks [@&#8203;chocky335](https://github.com/chocky335)! - Added `includes` option for plugin file scoping. Plugins can now be configured with glob patterns to restrict which files they run on. Use negated globs for exclusions. ```json { "plugins": [ "global-plugin.grit", { "path": "scoped-plugin.grit", "includes": ["src/**/*.ts", "!**/*.test.ts"] } ] } ``` - [#&#8203;9617](https://github.com/biomejs/biome/pull/9617) [`dcb99ef`](https://github.com/biomejs/biome/commit/dcb99ef0305d8431af40b526c449316bb8a70efa) Thanks [@&#8203;faizkhairi](https://github.com/faizkhairi)! - Ported [`useAriaActivedescendantWithTabindex`](https://biomejs.dev/linter/rules/use-aria-activedescendant-with-tabindex/) a11y rule to HTML. - [#&#8203;9496](https://github.com/biomejs/biome/pull/9496) [`1dfb829`](https://github.com/biomejs/biome/commit/1dfb8291a0a2340e7c9220f9126317a7490ec466) Thanks [@&#8203;aviraldua93](https://github.com/aviraldua93)! - Added HTML support for the [`noAriaHiddenOnFocusable`](https://biomejs.dev/linter/rules/no-aria-hidden-on-focusable/) accessibility lint rule, which enforces that `aria-hidden="true"` is not set on focusable elements. Focusable elements include native interactive elements (`<button>`, `<input>`, `<select>`, `<textarea>`), elements with `href` (`<a>`, `<area>`), elements with `tabindex >= 0`, and editing hosts (`contenteditable`). Includes an unsafe fix to remove the `aria-hidden` attribute. ```html <!-- Invalid: aria-hidden on a focusable element --> <button aria-hidden="true">Submit</button> <!-- Valid: aria-hidden on a non-focusable element --> <div aria-hidden="true">decorative content</div> ``` - [#&#8203;9792](https://github.com/biomejs/biome/pull/9792) [`f516854`](https://github.com/biomejs/biome/commit/f51685404f015a5c6f0fc87b9070ac5d9f0a7b6b) Thanks [@&#8203;Maximiliano-Zeballos](https://github.com/Maximiliano-Zeballos)! - Added the [`useSemanticElements`](https://biomejs.dev/linter/rules/use-semantic-elements/) lint rule for HTML. The rule now detects the use of `role` attributes in HTML elements and suggests using semantic elements instead. For example, the following code is now flagged: ```html <div role="navigation"></div> ``` The rule suggests using `<nav>` instead. - [#&#8203;9761](https://github.com/biomejs/biome/pull/9761) [`cbbb7d5`](https://github.com/biomejs/biome/commit/cbbb7d5bf21d8fb6db275da7adcc03c034538635) Thanks [@&#8203;Maximiliano-Zeballos](https://github.com/Maximiliano-Zeballos)! - Ported the [`useValidAriaProps`](https://biomejs.dev/linter/rules/use-valid-aria-props/) lint rule to HTML. This rule checks that all `aria-*` attributes used in HTML elements are valid ARIA attributes as defined by the WAI-ARIA specification. - [#&#8203;9928](https://github.com/biomejs/biome/pull/9928) [`aa82576`](https://github.com/biomejs/biome/commit/aa82576ff66e03924e07729051ac9bfc59cd5aa1) Thanks [@&#8203;aviraldua93](https://github.com/aviraldua93)! - Ported [`useValidAriaValues`](https://biomejs.dev/linter/rules/use-valid-aria-values/) to HTML. Biome now validates static `aria-*` attribute values in HTML elements against WAI-ARIA types, catching invalid values such as `aria-hidden="yes"`. - [#&#8203;10562](https://github.com/biomejs/biome/pull/10562) [`6642895`](https://github.com/biomejs/biome/commit/66428957e6ca393a802f365b8e643438f19a3039) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Promoted 73 nursery rules to stable groups. Four rules were renamed as part of the promotion: - `noFloatingClasses` is now [`noUnusedInstantiation`](https://biomejs.dev/linter/rules/no-unused-instantiation/), because the rule checks any discarded `new` expression, not only classes. - `noMultiStr` is now [`noMultilineString`](https://biomejs.dev/linter/rules/no-multiline-string/). - `useFind` is now [`useArrayFind`](https://biomejs.dev/linter/rules/use-array-find/). - `useSpread` is now [`useSpreadOverApply`](https://biomejs.dev/linter/rules/use-spread-over-apply/), because the rule enforces spread call arguments over `Function.apply()`, not array or object spread. ##### Correctness Promoted the following rules to the `correctness` group: - [`noBeforeInteractiveScriptOutsideDocument`](https://biomejs.dev/linter/rules/no-before-interactive-script-outside-document/) - [`noUnusedInstantiation`](https://biomejs.dev/linter/rules/no-unused-instantiation/) - [`useInlineScriptId`](https://biomejs.dev/linter/rules/use-inline-script-id/) (recommended, Next.js domain) - [`noVueVIfWithVFor`](https://biomejs.dev/linter/rules/no-vue-v-if-with-v-for/) (recommended, Vue domain) - [`useVueValidVBind`](https://biomejs.dev/linter/rules/use-vue-valid-v-bind/) (recommended, Vue domain) - [`useVueValidVElse`](https://biomejs.dev/linter/rules/use-vue-valid-v-else/) (recommended, Vue domain) - [`useVueValidVElseIf`](https://biomejs.dev/linter/rules/use-vue-valid-v-else-if/) (recommended, Vue domain) - [`useVueValidVHtml`](https://biomejs.dev/linter/rules/use-vue-valid-v-html/) (recommended, Vue domain) - [`useVueValidVIf`](https://biomejs.dev/linter/rules/use-vue-valid-v-if/) (recommended, Vue domain) - [`useVueValidVOn`](https://biomejs.dev/linter/rules/use-vue-valid-v-on/) (recommended, Vue domain) - [`useVueValidVText`](https://biomejs.dev/linter/rules/use-vue-valid-v-text/) (recommended, Vue domain) - [`useVueValidTemplateRoot`](https://biomejs.dev/linter/rules/use-vue-valid-template-root/) (recommended, Vue domain) - [`useVueValidVCloak`](https://biomejs.dev/linter/rules/use-vue-valid-v-cloak/) (recommended, Vue domain) - [`useVueValidVOnce`](https://biomejs.dev/linter/rules/use-vue-valid-v-once/) (recommended, Vue domain) - [`useVueValidVPre`](https://biomejs.dev/linter/rules/use-vue-valid-v-pre/) (recommended, Vue domain) - [`useVueVForKey`](https://biomejs.dev/linter/rules/use-vue-v-for-key/) (recommended, Vue domain) - [`noDuplicateAttributes`](https://biomejs.dev/linter/rules/no-duplicate-attributes/) (recommended) - [`noDuplicateArgumentNames`](https://biomejs.dev/linter/rules/no-duplicate-argument-names/) (recommended) - [`noDuplicateInputFieldNames`](https://biomejs.dev/linter/rules/no-duplicate-input-field-names/) (recommended) - [`noDuplicateVariableNames`](https://biomejs.dev/linter/rules/no-duplicate-variable-names/) (recommended) - [`noDuplicateEnumValueNames`](https://biomejs.dev/linter/rules/no-duplicate-enum-value-names/) (recommended) - [`useLoneAnonymousOperation`](https://biomejs.dev/linter/rules/use-lone-anonymous-operation/) (recommended) ##### Suspicious Promoted the following rules to the `suspicious` group: - [`noShadow`](https://biomejs.dev/linter/rules/no-shadow/) - [`noUnnecessaryConditions`](https://biomejs.dev/linter/rules/no-unnecessary-conditions/) - [`noParametersOnlyUsedInRecursion`](https://biomejs.dev/linter/rules/no-parameters-only-used-in-recursion/) - [`noUnknownAttribute`](https://biomejs.dev/linter/rules/no-unknown-attribute/) - [`useArraySortCompare`](https://biomejs.dev/linter/rules/use-array-sort-compare/) - [`noForIn`](https://biomejs.dev/linter/rules/no-for-in/) - [`noDuplicatedSpreadProps`](https://biomejs.dev/linter/rules/no-duplicated-spread-props/) - [`noEqualsToNull`](https://biomejs.dev/linter/rules/no-equals-to-null/) - [`noProto`](https://biomejs.dev/linter/rules/no-proto/) (recommended) - [`noUndeclaredEnvVars`](https://biomejs.dev/linter/rules/no-undeclared-env-vars/) (recommended, Turborepo domain) - [`noReturnAssign`](https://biomejs.dev/linter/rules/no-return-assign/) (default severity: `error`) - [`noDuplicateEnumValues`](https://biomejs.dev/linter/rules/no-duplicate-enum-values/) (recommended) - [`noVueArrowFuncInWatch`](https://biomejs.dev/linter/rules/no-vue-arrow-func-in-watch/) (recommended, Vue domain) - [`noNestedPromises`](https://biomejs.dev/linter/rules/no-nested-promises/) - [`noLeakedRender`](https://biomejs.dev/linter/rules/no-leaked-render/) - [`noDeprecatedMediaType`](https://biomejs.dev/linter/rules/no-deprecated-media-type/) (recommended) - [`noDuplicateGraphqlOperationName`](https://biomejs.dev/linter/rules/no-duplicate-graphql-operation-name/) - [`useRequiredScripts`](https://biomejs.dev/linter/rules/use-required-scripts/) ##### Style Promoted the following rules to the `style` group: - [`useVueMultiWordComponentNames`](https://biomejs.dev/linter/rules/use-vue-multi-word-component-names/) (recommended, Vue domain) - [`useVueDefineMacrosOrder`](https://biomejs.dev/linter/rules/use-vue-define-macros-order/) - [`noIncrementDecrement`](https://biomejs.dev/linter/rules/no-increment-decrement/) - [`noContinue`](https://biomejs.dev/linter/rules/no-continue/) - [`useSpreadOverApply`](https://biomejs.dev/linter/rules/use-spread-over-apply/) - [`noTernary`](https://biomejs.dev/linter/rules/no-ternary/) - [`noMultilineString`](https://biomejs.dev/linter/rules/no-multiline-string/) - [`noMultiAssign`](https://biomejs.dev/linter/rules/no-multi-assign/) - [`noExcessiveClassesPerFile`](https://biomejs.dev/linter/rules/no-excessive-classes-per-file/) - [`noExcessiveLinesPerFile`](https://biomejs.dev/linter/rules/no-excessive-lines-per-file/) - [`noVueOptionsApi`](https://biomejs.dev/linter/rules/no-vue-options-api/) - [`useErrorCause`](https://biomejs.dev/linter/rules/use-error-cause/) - [`useConsistentEnumValueType`](https://biomejs.dev/linter/rules/use-consistent-enum-value-type/) - [`useConsistentMethodSignatures`](https://biomejs.dev/linter/rules/use-consistent-method-signatures/) - [`useGlobalThis`](https://biomejs.dev/linter/rules/use-global-this/) (default severity: `warn`) - [`useDestructuring`](https://biomejs.dev/linter/rules/use-destructuring/) - [`useVueHyphenatedAttributes`](https://biomejs.dev/linter/rules/use-vue-hyphenated-attributes/) (recommended, Vue domain) - [`useVueConsistentVBindStyle`](https://biomejs.dev/linter/rules/use-vue-consistent-v-bind-style/) (recommended, Vue domain) - [`useVueConsistentVOnStyle`](https://biomejs.dev/linter/rules/use-vue-consistent-v-on-style/) (recommended, Vue domain) - [`noHexColors`](https://biomejs.dev/linter/rules/no-hex-colors/) - [`useConsistentGraphqlDescriptions`](https://biomejs.dev/linter/rules/use-consistent-graphql-descriptions/) - [`noRootType`](https://biomejs.dev/linter/rules/no-root-type/) - [`useLoneExecutableDefinition`](https://biomejs.dev/linter/rules/use-lone-executable-definition/) - [`useInputName`](https://biomejs.dev/linter/rules/use-input-name/) ##### Complexity Promoted the following rules to the `complexity` group: - [`useArrayFind`](https://biomejs.dev/linter/rules/use-array-find/) - [`noRedundantDefaultExport`](https://biomejs.dev/linter/rules/no-redundant-default-export/) (default severity: `warn`) - [`noUselessReturn`](https://biomejs.dev/linter/rules/no-useless-return/) - [`noDivRegex`](https://biomejs.dev/linter/rules/no-div-regex/) ##### Performance Promoted the following rules to the `performance` group: - [`noSyncScripts`](https://biomejs.dev/linter/rules/no-sync-scripts/) - [`noJsxPropsBind`](https://biomejs.dev/linter/rules/no-jsx-props-bind/) - [`useVueVapor`](https://biomejs.dev/linter/rules/use-vue-vapor/) ##### Security Promoted the following rules to the `security` group: - [`noScriptUrl`](https://biomejs.dev/linter/rules/no-script-url/) (recommended) ##### A11y Promoted the following rules to the `a11y` group: - [`noAmbiguousAnchorText`](https://biomejs.dev/linter/rules/no-ambiguous-anchor-text/) (recommended) - [#&#8203;10121](https://github.com/biomejs/biome/pull/10121) [`450f8e1`](https://github.com/biomejs/biome/commit/450f8e1c0a46e8c867a63a0842deaa50dee95176) Thanks [@&#8203;jongwan56](https://github.com/jongwan56)! - Biome now applies Git's local exclude file when VCS ignore files are enabled. Files listed in `.git/info/exclude` are skipped the same way as files listed in `.gitignore`, including in linked worktrees. - [#&#8203;9397](https://github.com/biomejs/biome/pull/9397) [`d5913c9`](https://github.com/biomejs/biome/commit/d5913c9d57b771b0b1c0097f8014017878cc14c2) Thanks [@&#8203;mvarendorff](https://github.com/mvarendorff)! - Added `ignore` option to the [noUnusedVariables](https://biomejs.dev/linter/rules/no-unused-variables/) rule. The option allows excluding identifiers by providing a list of ignored names. It also allows excluding kinds of identifiers from this rule entirely, which may be useful when loading classes dynamically. For example, unused classes as well as all unused variables, functions, etc. called "unused" may be ignored entirely with the following configuration: ```json { "ignore": { "*": ["unused"], "class": ["*"] } } ``` - [#&#8203;10089](https://github.com/biomejs/biome/pull/10089) [`71a21f0`](https://github.com/biomejs/biome/commit/71a21f0ab4fd32739331d3b3068c6c1ae6392290) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the lint rule [`noLabelWithoutControl`](https://biomejs.dev/linter/rules/no-label-without-control/) to HTML, which enforces that a label element or component has a text label and an associated input. ```html <label></label> ``` - [#&#8203;10015](https://github.com/biomejs/biome/pull/10015) [`1828261`](https://github.com/biomejs/biome/commit/182826178de9c1b23bad2e997c3567a9d5176ba2) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the HTML lint rule [`useAriaPropsSupportedByRole`](https://biomejs.dev/linter/rules/use-aria-props-supported-by-role/), which enforces that ARIA properties are valid for the roles that are supported by the element. ```html <a href="#" aria-checked></a> ``` - [#&#8203;10234](https://github.com/biomejs/biome/pull/10234) [`1a51569`](https://github.com/biomejs/biome/commit/1a51569229936b9ad1191d081ed6742e8342badd) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Added the `delimiterSpacing` formatter option. This option inserts spaces inside delimiters (after the opening delimiter and before the closing delimiter) when the content fits on a single line. Empty delimiters are not affected, and no space is added before the opening delimiter. The specific delimiters affected depend on the language. It can be configured globally via `formatter.delimiterSpacing` or per-language via `javascript.formatter.delimiterSpacing`, `json.formatter.delimiterSpacing`, and `css.formatter.delimiterSpacing`. Defaults to `false`. ```diff - callFn(foo) + callFn( foo ) ``` ```diff - const arr = [1, 2, 3]; + const arr = [ 1, 2, 3 ]; ``` ##### JavaScript When enabled, Biome inserts spaces inside parentheses (e.g., `foo( a, b )`), square brackets (e.g., `[ a, b ]`), template literal interpolations (e.g., `${ expr }`), and the logical NOT operator (e.g., `! x`, but in chains only after the last one: `!! x`). Only applies when the content fits on a single line. Empty delimiters and the space before the opening delimiter are not affected. ```diff - if (condition) {} + if ( condition ) {} ``` ```diff - `Hello ${name}!` + `Hello ${ name }!` ``` ##### JSX When enabled, Biome inserts spaces inside JSX expression braces (e.g., `attr={ value }`) and spread attributes (e.g., `{ ...props }`). Only applies when the content fits on a single line. Empty delimiters are not affected. ```diff - <Foo bar={value} /> + <Foo bar={ value } /> ``` ##### TypeScript When enabled, Biome inserts spaces inside TypeScript angle brackets (e.g., `foo< T >()`), indexed access types (e.g., `T[ K ]`), mapped types, tuple types, type parameters, and index signatures. Only applies when the content fits on a single line. Empty delimiters are not affected. ```diff - type Result = Map<string, number>; + type Result = Map< string, number >; ``` ##### JSON When enabled, Biome inserts spaces inside square brackets when the content fits on a single line. Empty brackets are not affected. ```diff - [1, 2, 3] + [ 1, 2, 3 ] ``` ##### CSS When enabled, Biome inserts spaces inside parentheses and square brackets when the content fits on a single line. Empty delimiters are not affected. ```diff - rgba(0, 0, 0, 1) + rgba( 0, 0, 0, 1 ) ``` ```diff - [data-attr] + [ data-attr ] ``` - [#&#8203;10461](https://github.com/biomejs/biome/pull/10461) [`6bac1c3`](https://github.com/biomejs/biome/commit/6bac1c3457d396215e4daed5fc59eaf23b42f4eb) Thanks [@&#8203;TXWSLYF](https://github.com/TXWSLYF)! - Implements [#&#8203;9445](https://github.com/biomejs/biome/issues/9445). Added the `allowImplicit` option to [`useIterableCallbackReturn`](https://biomejs.dev/linter/rules/use-iterable-callback-return/). When enabled, callbacks can use `return;` to implicitly return `undefined`, matching ESLint's `array-callback-return` rule. - [#&#8203;9571](https://github.com/biomejs/biome/pull/9571) [`5a8eb75`](https://github.com/biomejs/biome/commit/5a8eb755fe07b38760d2b72ec46e24cd108f6619) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added configurable options to the [`useNumericSeparators`](https://biomejs.dev/linter/rules/use-numeric-separators/) rule. Users can now customize the minimum number of digits required before adding separators and the group length for each type of numeric literal (`binary`, `octal`, `decimal`, `hexadecimal`). ```json { "linter": { "rules": { "style": { "useNumericSeparators": { "level": "error", "options": { "decimal": { "minimumDigits": 7, "groupLength": 3 }, "hexadecimal": { "minimumDigits": 4, "groupLength": 2 } } } } } } } ``` - [#&#8203;10067](https://github.com/biomejs/biome/pull/10067) [`6064312`](https://github.com/biomejs/biome/commit/60643120b5593104b311e184cf9581b9c7c2254d) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the lint rule [`useFocusableInteractive`](https://biomejs.dev/linter/rules/use-focusable-interactive/) to HTML, which enforces elements with an interactive role and interaction handler to be focusable. **Invalid**: ```html <div role="button"></div> ``` - [#&#8203;10026](https://github.com/biomejs/biome/pull/10026) [`fb42ac4`](https://github.com/biomejs/biome/commit/fb42ac42079ec7b8e699a507bce332f4446ac7f2) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the HTML lint rule [`noNoninteractiveElementInteractions`](https://biomejs.dev/linter/rules/no-noninteractive-element-interactions/), which disallows use event handlers on non-interactive elements. **Invalid**: ```html <div onclick="myFunction()">button</div> ``` - [#&#8203;10000](https://github.com/biomejs/biome/pull/10000) [`2093e3e`](https://github.com/biomejs/biome/commit/2093e3ee2a615abecae159d35a5a17fe0df5f506) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the new assist action [`useSortedEnumMembers`](https://biomejs.dev/assist/actions/use-sorted-enum-members/), which sorts TypeScript & GraphQL enum members. **Invalid**: ```graphql enum Role { SUPER_ADMIN ADMIN USER GOD } ``` - [#&#8203;10013](https://github.com/biomejs/biome/pull/10013) [`ad01d3d`](https://github.com/biomejs/biome/commit/ad01d3d882276b070433822f01cdf6afed63ca4e) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added the HTML lint rule [`useValidAutocomplete`](https://biomejs.dev/linter/rules/use-valid-autocomplete/), which enforces using valid values for the `autocomplete` attribute on `input` elements. ```html <input autocomplete="incorrect" /> ``` ##### Patch Changes - [#&#8203;10498](https://github.com/biomejs/biome/pull/10498) [`995c1ff`](https://github.com/biomejs/biome/commit/995c1ffeca039787c93370fed8b970a057e9c073) Thanks [@&#8203;citadelgrad](https://github.com/citadelgrad)! - Added the nursery rule [`useReactFunctionComponentDefinition`](https://biomejs.dev/linter/rules/use-react-function-component-definition), which enforces a consistent function type for named React function components. For example, the following snippet triggers the rule by default. ```jsx const MyComponent = (props) => { return <div>{props.name}</div>; }; ``` - [#&#8203;9974](https://github.com/biomejs/biome/pull/9974) [`ff635a9`](https://github.com/biomejs/biome/commit/ff635a90da3567a9006ae947b6c5983d87dfbb9f) Thanks [@&#8203;pkallos](https://github.com/pkallos)! - Added `ignoreMixedLogicalExpressions` to [useNullishCoalescing](https://biomejs.dev/linter/rules/use-nullish-coalescing/), partially addressing [#&#8203;9232](https://github.com/biomejs/biome/issues/9232). When enabled, Biome ignores `||` and `||=` mixed with `&&` in the same expression tree. - [#&#8203;10503](https://github.com/biomejs/biome/pull/10503) [`c656679`](https://github.com/biomejs/biome/commit/c656679d1f9e725a42e5d60fb3b9e76bb03d7f88) Thanks [@&#8203;Mokto](https://github.com/Mokto)! - Added the new nursery rule `useSvelteRequireEachKey`, a Svelte lint rule that reports `{#each}` blocks with item bindings that are missing a key. - [#&#8203;10516](https://github.com/biomejs/biome/pull/10516) [`0f29b83`](https://github.com/biomejs/biome/commit/0f29b8361ba3cd11bdbfb91f8ff722184cfadf08) Thanks [@&#8203;Dotify71](https://github.com/Dotify71)! - Added [`useIncludes`](https://biomejs.dev/linter/rules/use-includes/) to the nursery group. This rule flags comparisons of `String.prototype.indexOf()` or `Array.prototype.indexOf()` against `-1` and suggests replacing them with the clearer `includes()` / `!includes()` form. - [#&#8203;10487](https://github.com/biomejs/biome/pull/10487) [`0c03ee3`](https://github.com/biomejs/biome/commit/0c03ee3deee068220175c3599e6bc3c4ed8ad247) Thanks [@&#8203;Mokto](https://github.com/Mokto)! - Fixed a Svelte parser error that incorrectly required a binding variable after `{:then}` and `{:catch}`. Biome now correctly accepts `{:then}` and `{:catch}` without a binding, as well as the `{#await expr then}` and `{#await expr catch}` shorthand forms. - [#&#8203;10566](https://github.com/biomejs/biome/pull/10566) [`a4a294c`](https://github.com/biomejs/biome/commit/a4a294c3c1128fc5b38634262d499d3d2601bf3b) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [`useVueHyphenatedAttributes`](https://biomejs.dev/linter/rules/use-vue-hyphenated-attributes/): The rule now only reports diagnostics in Vue files and ignores SVG elements. - [#&#8203;10565](https://github.com/biomejs/biome/pull/10565) [`72ccf3b`](https://github.com/biomejs/biome/commit/72ccf3b042c4258f9871ff5b99d87f879cecccde) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [`useVueConsistentVBindStyle`](https://biomejs.dev/linter/rules/use-vue-consistent-v-bind-style/): The rule no longer reports argument-less `v-bind` directives because they cannot be converted to shorthand syntax. - [#&#8203;10591](https://github.com/biomejs/biome/pull/10591) [`6e8557b`](https://github.com/biomejs/biome/commit/6e8557b1b8e49ce2383f6089a46624eb030178ad) Thanks [@&#8203;xsourabhsharma](https://github.com/xsourabhsharma)! - Fixed [#&#8203;10563](https://github.com/biomejs/biome/issues/10563): Biome now parses comma-separated CSS Modules `composes` values, such as `composes: classA from "./a.css", classB from "./b.css";`. - [#&#8203;10603](https://github.com/biomejs/biome/pull/10603) [`174b21b`](https://github.com/biomejs/biome/commit/174b21b52993fc3e0237ceefe97c0d71c9b5264e) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Fixed CSS formatting for `grid-template-areas` declarations with comments before multiline values. Biome now keeps grid area rows aligned instead of adding an extra declaration-boundary indent. ```diff .grid { grid-template-areas: /* row */ - "header header" - "footer footer"; + "header header" + "footer footer"; } ``` - [#&#8203;10542](https://github.com/biomejs/biome/pull/10542) [`c3f07f7`](https://github.com/biomejs/biome/commit/c3f07f773edeb7f098c778392c5e2d6bb92b78fb) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10513](https://github.com/biomejs/biome/issues/10513): Biome no longer rejects literal `\u` sequences in quoted HTML attribute values. - [#&#8203;10108](https://github.com/biomejs/biome/pull/10108) [`24e51d6`](https://github.com/biomejs/biome/commit/24e51d6edebaee0ffb938bc20633d9c3403110c9) Thanks [@&#8203;IxxyDev](https://github.com/IxxyDev)! - Fixed [#&#8203;6611](https://github.com/biomejs/biome/issues/6611): [`noUnnecessaryConditions`](https://biomejs.dev/linter/rules/no-unnecessary-conditions/) now uses type information to detect more redundant conditions, including `?.`, `??`, `||`, `&&`, comparisons against `null`/`undefined` on non-nullish operands, and `case` clauses that can never match the `switch` value. - [#&#8203;10568](https://github.com/biomejs/biome/pull/10568) [`eb1ed0e`](https://github.com/biomejs/biome/commit/eb1ed0e90395a07e64ee763fe15ae00fb77682e0) Thanks [@&#8203;harsha-cpp](https://github.com/harsha-cpp)! - Fixed [#&#8203;10564](https://github.com/biomejs/biome/issues/10564): `useAriaPropsForRole` no longer reports false positives for Vue v-bind shorthand bindings (`:aria-checked`, `:aria-level`, etc.). - [#&#8203;10570](https://github.com/biomejs/biome/pull/10570) [`2ceb4fe`](https://github.com/biomejs/biome/commit/2ceb4fe437b77b08a60ad48efde2a6c311b7d2e3) Thanks [@&#8203;Conaclos](https://github.com/Conaclos)! - Improved [`noTsIgnore`](https://biomejs.dev/linter/rules/no-ts-ignore/). The rule now reports more precisely the range of the `@ts-ignore` comment. - [#&#8203;10520](https://github.com/biomejs/biome/pull/10520) [`b55d10f`](https://github.com/biomejs/biome/commit/b55d10f5e8f3099b3f246911ca19cc79758d55e0) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10519](https://github.com/biomejs/biome/issues/10519): Vue `v-on` event handlers with multiple inline statements are now parsed consistently with Vue. - [#&#8203;10204](https://github.com/biomejs/biome/pull/10204) [`ebbf0bd`](https://github.com/biomejs/biome/commit/ebbf0bd382059936ac00de29fc58931728f854d9) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Improved the performance of the Biome linter. The improvements are more visible in bigger projects that have more than \~1k files. Early tests showed that in a code base with \~2k files, Biome took less than 26% of time to finish the command. - [#&#8203;10546](https://github.com/biomejs/biome/pull/10546) [`e39bb2c`](https://github.com/biomejs/biome/commit/e39bb2c23063ad0384a12e01d666909fd6b26735) Thanks [@&#8203;tim-we](https://github.com/tim-we)! - Fixed [`#10536`](https://github.com/biomejs/biome/issues/10536): [noUnknownFunction](https://biomejs.dev/linter/rules/no-unknown-function/) no longer flagged CSS `contrast-color()` as unknown. `contrast-color()` is Baseline 2026. - [#&#8203;8012](https://github.com/biomejs/biome/pull/8012) [`2be0264`](https://github.com/biomejs/biome/commit/2be02648a090153a93cf71fb63ef68feefd495c2) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Improved the performance of the formatter in some cases. The formatter is now up to \~20% faster at formatting files. - [#&#8203;10467](https://github.com/biomejs/biome/pull/10467) [`9a5855e`](https://github.com/biomejs/biome/commit/9a5855e4191c98149f8278289569b2272b992684) Thanks [@&#8203;Netail](https://github.com/Netail)! - Added a new nursery rule [`noRestrictedDependencies`](https://biomejs.dev/linter/rules/no-restricted-dependencies/), which flags imports and `package.json` dependency entries that have better alternatives in e18e's module replacement data. For example, the package `globby` is reported because there's a better alternative: ```js import glob from "globby"; ``` ```json { "dependencies": { "globby": "x.x.x" } } ``` - [#&#8203;10470](https://github.com/biomejs/biome/pull/10470) [`84b43c5`](https://github.com/biomejs/biome/commit/84b43c5969569cb3eea3d51ea6c602276723306b) Thanks [@&#8203;ShaharAviram1](https://github.com/ShaharAviram1)! - Fixed [#&#8203;10447](https://github.com/biomejs/biome/issues/10447): now the rule [`noProcessEnv`](https://biomejs.dev/linter/rules/no-process-env) detects the use of `env` when it's imported from `process` and `node:process`. - [#&#8203;10556](https://github.com/biomejs/biome/pull/10556) [`7ff6b16`](https://github.com/biomejs/biome/commit/7ff6b165f2f62a0836446dee889d9868f12fb06e) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;10492](https://github.com/biomejs/biome/issues/10492): Biome no longer crashes with a stack overflow on certain code when a type-aware rule such as [`noFloatingPromises`](https://biomejs.dev/linter/rules/no-floating-promises/), [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises/), or [`noUnnecessaryConditions`](https://biomejs.dev/linter/rules/no-unnecessary-conditions/) is enabled. For example, the following code used to crash Biome: ```js function f(visitor) { let ctrl = visitor(); for (const x of [0]) ctrl = ctrl(); } ``` - [#&#8203;10532](https://github.com/biomejs/biome/pull/10532) [`1da3c75`](https://github.com/biomejs/biome/commit/1da3c7573cdb1d097fc1773fee686140d95f3f35) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - CSS declarations with comments before `:` or after `!important` now preserve spaces before `:` and `;`. ```diff .selector { - padding/* name */: 1px; - color: red !important /* note */; + padding/* name */ : 1px; + color: red !important /* note */ ; } ``` - [#&#8203;10491](https://github.com/biomejs/biome/pull/10491) [`a1b5834`](https://github.com/biomejs/biome/commit/a1b5834d4968fd518cc4adfa0e8b4b65b2232637) Thanks [@&#8203;Mokto](https://github.com/Mokto)! - Fixed the Svelte parser rejecting `{#each}` blocks where the binding uses object destructuring with property renaming, e.g. `{#each items as { id, component: Filter }}`. Biome now correctly parses and formats these rename bindings. - [#&#8203;10490](https://github.com/biomejs/biome/pull/10490) [`99bc7df`](https://github.com/biomejs/biome/commit/99bc7df1d1cbb599e9713da56c29763cd04bb53c) Thanks [@&#8203;Mokto](https://github.com/Mokto)! - Fixed the CSS parser rejecting comma-separated selector lists inside `:global()` and `:local()` pseudo-class functions. Biome now correctly parses `:global(.foo, .bar)`. - [#&#8203;10543](https://github.com/biomejs/biome/pull/10543) [`c394fae`](https://github.com/biomejs/biome/commit/c394faeaa27f9f7db8ba075afc6657c0245d8276) Thanks [@&#8203;mangod12](https://github.com/mangod12)! - Fixed [#&#8203;10477](https://github.com/biomejs/biome/issues/10477): The RDJSON reporter now emits code replacement text for fix suggestions instead of the human-readable fix description. - [#&#8203;10530](https://github.com/biomejs/biome/pull/10530) [`e8e1e6a`](https://github.com/biomejs/biome/commit/e8e1e6aa1b39d1e19d33c12d4b56d6d3fd01a7ce) Thanks [@&#8203;Conaclos](https://github.com/Conaclos)! - Fixed [#&#8203;10493](https://github.com/biomejs/biome/issues/10493): [`useImportType`](https://biomejs.dev/linter/rules/use-import-type/) now correctly separates types from a default named import when all imports are types and the `style` option is set to `separatedType`. - [#&#8203;10555](https://github.com/biomejs/biome/pull/10555) [`263c7cc`](https://github.com/biomejs/biome/commit/263c7ccd12cd8c0d4527fdf4797c652a223df012) Thanks [@&#8203;Mokto](https://github.com/Mokto)! - Improved Svelte lint rule accuracy for quoted attribute values containing `{expression}` interpolations. - [`noRedundantAlt`](https://biomejs.dev/linter/rules/no-redundant-alt/) no longer emits false positives when the alt text contains an interpolation, e.g. `alt="image of {person}"`. - [`useButtonType`](https://biomejs.dev/linter/rules/use-button-type/) no longer emits false positives for dynamic button types written as `type="{dynamicType}"`. - [`noScriptUrl`](https://biomejs.dev/linter/rules/no-script-url/) no longer emits false positives for dynamic hrefs such as `href="{url}"`. - [#&#8203;10489](https://github.com/biomejs/biome/pull/10489) [`96ef9a4`](https://github.com/biomejs/biome/commit/96ef9a4c2647a71d917485f6791e151cf8b88c96) Thanks [@&#8203;Mokto](https://github.com/Mokto)! - Fixed Svelte `{#each}` parser incorrectly rejecting TypeScript `as const` type assertions in the iterable expression. Biome now correctly parses `{#each arr as const as item}`. - [#&#8203;10539](https://github.com/biomejs/biome/pull/10539) [`935c59a`](https://github.com/biomejs/biome/commit/935c59a6657022c37c9b9933c66cc29c236e5aff) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Improved how diagnostics print long lines of code, for example minified files where the entire source code is printed in one line. ### [`v2.4.16`](https://github.com/biomejs/biome/blob/HEAD/packages/@biomejs/biome/CHANGELOG.md#2416) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.15...@biomejs/biome@2.4.16) ##### Patch Changes - [#&#8203;10329](https://github.com/biomejs/biome/pull/10329) [`ef764d5`](https://github.com/biomejs/biome/commit/ef764d51b9f5be18ec5a4f9b4dce732512e5d805) Thanks [@&#8203;Conaclos](https://github.com/Conaclos)! - Fixed an issue where diagnostics showed an incorrect location in Astro files. - [#&#8203;10363](https://github.com/biomejs/biome/pull/10363) [`50aa415`](https://github.com/biomejs/biome/commit/50aa4157599a1ac5c77c13bce81f5c87240beff0) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed HTML formatting for a case where comments could cause the formatter to split up a closing tag, which would cause the resulting HTML to be syntactically invalid. Input: ```html <span ><!-- 1 --><span>a</span ><!-- 2 --><span>b</span ><!-- 3 --></span> ``` Output: ```diff <span ><!-- 1 - --> <span>a</span<!-- 2 - --> ><span>b</span><!-- 3 + --><span>a</span><!-- 2 + --><span>b</span><!-- 3 --></span > ``` - [#&#8203;10465](https://github.com/biomejs/biome/pull/10465) [`0c718da`](https://github.com/biomejs/biome/commit/0c718da81770f47d65845bc1a006f99512d9359b) Thanks [@&#8203;dfedoryshchev](https://github.com/dfedoryshchev)! - Fixed diagnostics emitted by the `noUntrustedLicenses` rule. - [#&#8203;10358](https://github.com/biomejs/biome/pull/10358) [`05c2617`](https://github.com/biomejs/biome/commit/05c26176573534a0abfa92d454d244f9569bc77d) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10356](https://github.com/biomejs/biome/issues/10356): `biome rage --linter` now displays rules enabled through linter domains in the enabled rules list. - [#&#8203;10300](https://github.com/biomejs/biome/pull/10300) [`950247c`](https://github.com/biomejs/biome/commit/950247c389e693c16b47d61d8ef0f1b85d1a1b02) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10265](https://github.com/biomejs/biome/issues/10265): Svelte function bindings such as `bind:value={get, set}` are now parsed more precisely, so [`noCommaOperator`](https://biomejs.dev/linter/rules/no-comma-operator/) won't emit false positives for that syntax anymore. - [#&#8203;9786](https://github.com/biomejs/biome/pull/9786) [`e71f584`](https://github.com/biomejs/biome/commit/e71f58490f3121432d1bc24ae5330ecf96391a40) Thanks [@&#8203;MeGaNeKoS](https://github.com/MeGaNeKoS)! - Fixed [#&#8203;8480](https://github.com/biomejs/biome/issues/8480): [`useDestructuring`](https://biomejs.dev/linter/rules/use-destructuring/) now provides `variableDeclarator` and `assignmentExpression` options to control which contexts enforce destructuring, matching ESLint's `prefer-destructuring` configuration. Both default to `{array: true, object: true}`. The diagnostic for object destructuring in assignment expressions now instructs users to wrap the assignment in parentheses. - [#&#8203;10425](https://github.com/biomejs/biome/pull/10425) [`1948b72`](https://github.com/biomejs/biome/commit/1948b7242e092ed0cfcf501ef6f119202b8ea93b) Thanks [@&#8203;sjh9714](https://github.com/sjh9714)! - Fixed [#&#8203;10244](https://github.com/biomejs/biome/issues/10244): The `useOptionalChain` rule now detects negated guard inequality chains like `!foo || foo.bar !== "x"`. - [#&#8203;10442](https://github.com/biomejs/biome/pull/10442) [`001f94f`](https://github.com/biomejs/biome/commit/001f94f696d9baca3c231d39895a01d4dd528d52) Thanks [@&#8203;ematipico](https://github.com/ematipico)! - Fixed [#&#8203;10411](https://github.com/biomejs/biome/issues/10411): [`noMisusedPromises`](https://biomejs.dev/linter/rules/no-misused-promises/) no longer causes a stack overflow when a nested function returns an object with shorthand properties that shadow destructured variables from an outer scope. - [#&#8203;10318](https://github.com/biomejs/biome/pull/10318) [`9b1577f`](https://github.com/biomejs/biome/commit/9b1577fa400279d9b0222cbc920cfa9ddcf1c9d6) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Added support for `formatter.trailingCommas` in overrides. This option was previously available in the top-level formatter configuration but missing from formatter overrides. - [#&#8203;10319](https://github.com/biomejs/biome/pull/10319) [`2e37709`](https://github.com/biomejs/biome/commit/2e3770923f9fb4e33606113e726014f7b63730d0) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed Vue and Svelte formatting for standalone interpolations in inline elements. Biome now preserves existing newlines in cases like: ```diff - <span> {{ value }} </span> + <span> + {{ value }} + </span> ``` - [#&#8203;10365](https://github.com/biomejs/biome/pull/10365) [`0a58eb0`](https://github.com/biomejs/biome/commit/0a58eb0982460b757a26f94d958a7e40c0686227) Thanks [@&#8203;Netail](https://github.com/Netail)! - Fixed [#&#8203;10361](https://github.com/biomejs/biome/issues/10361): [`noUnusedFunctionParameters`](https://biomejs.dev/linter/rules/no-unused-function-parameters/) now mentions the parameter name in the diagnostic. - [#&#8203;10439](https://github.com/biomejs/biome/pull/10439) [`df6b867`](https://github.com/biomejs/biome/commit/df6b867bb6fd210cc75ac03d832e7281eced5b61) Thanks [@&#8203;denbezrukov](https://github.com/denbezrukov)! - Fixed CSS and SCSS formatting for comments around declaration colons so comments between property names, colons, and values stay at the same boundary as Prettier. ```diff .selector { - color: /* red, */ - blue; + color: /* red, */ blue; } ``` - [#&#8203;10344](https://github.com/biomejs/biome/pull/10344) [`b30208c`](https://github.com/biomejs/biome/commit/b30208c06365907d6fb376f030bc75bbf5e3dea9) Thanks [@&#8203;siketyan](https://github.com/siketyan)! - Fixed [`#10123`](https://github.com/biomejs/biome/issues/10123): Corrected the [`noReactNativeDeepImports`](https://biomejs.dev/linter/rules/no-react-native-deep-imports/) source rule to point to the proper upstream rule, so users can migrate from the original rule correctly. - [#&#8203;10328](https://github.com/biomejs/biome/pull/10328) [`b59133f`](https://github.com/biomejs/biome/commit/b59133fd2a8afa33564914df531f7f752b48ecee) Thanks [@&#8203;dyc3](https://github.com/dyc3)! - Fixed [#&#8203;10309](https://github.com/biomejs/biome/issues/10309): Biome no longer adds newlines to Astro frontmatter when linter or assist `--write` mode is enabled. </details> <details> <summary>haydenbleasel/ultracite (ultracite)</summary> ### [`v7.11.1`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.11.1) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.11.0...ultracite@7.11.1) ##### Patch Changes - [`24b2797`](https://github.com/haydenbleasel/ultracite/commit/24b2797): Update oxfmt to 0.67.0 and re-target the markdown `:::` fence patch to the new dist chunk. The release changes no options; it fixes CSS/SCSS/Less comment preservation and a few JSDoc-cast edge cases in member chains. - [`24b2797`](https://github.com/haydenbleasel/ultracite/commit/24b2797): Update oxlint to 1.82.0. The release adds and removes no rules, so the presets are unchanged apart from one new option: `no-unmodified-loop-condition` now runs with `checkConditionalExpressions: true` in the oxlint and ESLint core presets, so each branch of a ternary in a loop condition must be modified inside the loop rather than only the expression as a whole. - [`24b2797`](https://github.com/haydenbleasel/ultracite/commit/24b2797): Update the ESLint family: `@angular-eslint/eslint-plugin` 22.5, `@typescript-eslint/*` 8.70, `eslint-plugin-solid` 0.18, `eslint-plugin-vue` 10.11, `eslint-plugin-jsdoc` 64.3.8, `eslint-plugin-cypress` 7.0.2, `@darraghor/eslint-plugin-nestjs-typed` 7.5.2 and `prettier-plugin-astro` 1.0. The dynamic presets pick up the seven new rules automatically: `@typescript-eslint/no-generated-empty-object-type`, `@angular-eslint/reactive-context-must-read-signal`, `vue/no-shadow-native-events`, and Solid's `no-boolean-enumerated-attribute`, `no-store-mutation-outside-setter`, `no-unused-signal` and `no-write-in-pure-computation`. Note that `prettier-plugin-astro` 1.0 is a rewrite on the Astro 7 Rust compiler (Node 22.12+); expect whitespace diffs on first run and mirror any custom `compressHTML` via its new `astroCompressHTML` option. - [`24b2797`](https://github.com/haydenbleasel/ultracite/commit/24b2797): Refresh the stylelint lock to 17.15.0 and enable its new `selector-no-unmatchable` rule, which flags selectors that can never match (for example `label:checked`, `::before:first-child` or `:is(::before)`). - [`a71dda4`](https://github.com/haydenbleasel/ultracite/commit/a71dda4): Stop sorting object keys across the whole TanStack presets, not just route files. TanStack Query mutation options are order-sensitive too: TypeScript infers the `onMutate` context from context-sensitive callbacks in source order, so moving `onError`/`onSettled` above `onMutate` turns the context into `{}` and `ultracite fix` broke type-correct code (`TS2339: Property '...' does not exist on type '{}'`). Mutation and query options live anywhere (hooks, components, colocated files), so the route-file exemption could not cover them. `ultracite/oxlint/tanstack` now sets `sort-keys` to `off` and `ultracite/biome/tanstack` now sets `useSortedKeys` to `off` for all files. - [`a9db61c`](https://github.com/haydenbleasel/ultracite/commit/a9db61c): Disable `github/filenames-match-regex` for file-based route directories (`**/routes/**`) in the oxlint js-plugins preset, matching the existing `unicorn/filename-case` exemption in the TanStack preset. TanStack Router filenames such as `__root.tsx`, `$.tsx`, and `posts.$postId.tsx` no longer fail the GitHub filename rule. Resolves [#&#8203;799](https://github.com/haydenbleasel/ultracite/issues/799). ### [`v7.11.0`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.11.0) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.10.8...ultracite@7.11.0) ##### Minor Changes - [`d5d241f`](https://github.com/haydenbleasel/ultracite/commit/d5d241f): Add `ultracite upgrade`, and make version drift between Ultracite and its linter visible instead of a crash. Bumping `ultracite` without bumping the linter fails on the next `check`/`fix` with Biome's `Found an unknown key` error (and the equivalent for ESLint and Oxlint), because each release enables rules from a specific linter version. - `ultracite upgrade` installs the latest `ultracite`, prints a release-notes link for the versions you crossed, then hands off to the freshly installed CLI to reinstall your toolchain at the versions that release was verified with: Biome; ESLint, Prettier, Stylelint and the plugins the preset imports; or Oxlint and Oxfmt. Optional extras already in your `package.json` (framework plugins, Oxlint JS plugins, `oxlint-tsgolint`) are bumped as well. Config files are never rewritten, and the run ends with the same diagnostics as `doctor`. - `ultracite doctor` now checks the installed Biome, ESLint, Prettier, Stylelint, Oxlint and Oxfmt versions against the range this release supports. Too old fails the check and points at `ultracite upgrade`; newer than the verified range only warns. - The supported ranges are declared as optional peer dependencies so package managers warn when they drift: `@biomejs/biome ^2.5.0`, `eslint ^10.0.0`, `prettier ^3.0.0`, `stylelint ^17.0.0`, `oxlint ^1.79.0`, `oxfmt >=0.40.0`. `ultracite init` now installs Prettier and Stylelint from those ranges instead of `latest`. Requires Biome >= 2.5.0, ESLint >= 10.0.0, Prettier >= 3.0.0, Stylelint >= 17.0.0, Oxlint >= 1.79.0 and Oxfmt >= 0.40.0. ##### Patch Changes - [`27d06f2`](https://github.com/haydenbleasel/ultracite/commit/27d06f2): Update dependencies (`@clack/prompts`, `semver`, `zod`, ESLint plugins). - [`d322691`](https://github.com/haydenbleasel/ultracite/commit/d322691): Default `ultracite init` to Oxlint + Oxfmt when `--linter` is omitted in quiet or non-interactive mode - [`c677cf5`](https://github.com/haydenbleasel/ultracite/commit/c677cf5): Recommend Oxlint + Oxfmt in the `ultracite init` linter prompt and list it first - [`c5be848`](https://github.com/haydenbleasel/ultracite/commit/c5be848): Disable `no-use-before-define` in TanStack Router route files for the oxlint tanstack preset. File routes are mutually recursive (`Route` references the component, and the component calls `Route.useParams()`), so no declaration order could satisfy the rule. ### [`v7.10.8`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.10.8) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.10.7...ultracite@7.10.8) ##### Patch Changes - [`2a43fdd`](https://github.com/haydenbleasel/ultracite/commit/2a43fdd): Turn off `unicorn/prefer-reflect-apply` in the `ultracite/oxlint/anti-slop` preset. When extended after `ultracite/oxlint/core`, the core rule recommended rewriting `Function#apply()` to `Reflect.apply()`, which anti-slop's `no-reflect-apply` then rejected, leaving no way to satisfy both. Direct-call guidance for `.apply()` still comes from `eslint/prefer-spread` and `eslint/no-useless-call`. - [`03196df`](https://github.com/haydenbleasel/ultracite/commit/03196df): Update `@biomejs/biome` to 2.5.12. Releases 2.5.10 through 2.5.12 only add nursery rules, which the Biome presets exclude, so the presets are unchanged. The releases also carry linter and formatter fixes, including fewer `noUnusedVariables` false positives on merged interfaces, namespaces, and overload type parameters, an unsafe-by-default fix for `noThisInStatic`, and a large batch of Astro expression parsing fixes. - [`031b867`](https://github.com/haydenbleasel/ultracite/commit/031b867): Update oxfmt to 0.66.0. The 0.65 and 0.66 releases are formatter fixes only, mainly around comment placement between a statement head and its body, suppressed statements (decorators, typecast parens, semicolons), custom side-effect groups in `sortImports`, CommonMark list interruption in JSDoc, and trailing whitespace in YAML block scalars. The `:::` container-directive fence patch is re-targeted to the new markdown bundle; the patched code itself is unchanged. - [`54affee`](https://github.com/haydenbleasel/ultracite/commit/54affee): Update oxlint to 1.81.0. The 1.80 and 1.81 releases add no rules and remove none, so the presets are unchanged and the peer range stays at ^1.79.0. Notable fixes carried in: `no-use-before-define` now runs on JS and JSX files, `object-shorthand` preserves `__proto__` semantics, `unicorn/prefer-math-min-max` no longer applies an unsafe autofix, and JS plugin diagnostics with invalid or reversed locations are clamped instead of crashing. - [`0b058d1`](https://github.com/haydenbleasel/ultracite/commit/0b058d1): Fix `ultracite fix --codex` failing on recent Codex CLI releases. The Codex adapter invoked `codex exec --full-auto`, a flag Codex has since removed, so every attempt failed at argument parsing. It now runs `codex exec --sandbox workspace-write`, the equivalent non-interactive, workspace-scoped mode, which is also accepted by older Codex versions. Resolves [#&#8203;794](https://github.com/haydenbleasel/ultracite/issues/794). - [`e2346bb`](https://github.com/haydenbleasel/ultracite/commit/e2346bb): Update the ESLint family to latest: eslint 10.9.1, typescript-eslint 8.69.0, eslint-plugin-unicorn 74, eslint-plugin-solid 0.17, eslint-plugin-jsdoc 64.3.5, eslint-plugin-react-doctor and oxlint-plugin-react-doctor 0.9.13, globals 17.12, and the angular, nestjs-typed, next, tanstack-query, cypress, html, jest and storybook plugins. The dynamic presets pick up the new rules automatically: the solid preset gains the eleven rules added in eslint-plugin-solid 0.16 and 0.17 (`removed-api`, `no-single-arg-create-effect`, `no-accessor-as-prop`, `valid-use-server`, `require-async-server-function`, `no-invalid-server-capture`, `no-browser-globals-in-server-function`, `no-module-scope-reactive-primitive`, `no-restated-default-options`, `prefer-onSettled-for-side-effects`, `prefer-structured-class`), which only report Solid 2.0 issues when `settings.solid.version` is set to 2 and stay silent on Solid 1.x code; the nestjs preset gains `forward-ref-injection-should-use-wrapper-type`, `swagger-file-upload-should-be-documented` and `uploaded-file-should-be-validated`. The curated jsdoc and react-doctor lists are unchanged. No enabled rule was removed or deprecated, and the ESLint/oxlint parity check still passes. - [`7b0456e`](https://github.com/haydenbleasel/ultracite/commit/7b0456e): `ultracite fix` now runs lint fixes before the formatter: oxlint before oxfmt, and ESLint then Stylelint before Prettier. A fixer can insert unformatted code, such as the braces `curly` adds, the imports `consistent-type-specifier-style` splits, or the font names Stylelint requotes, and running the formatter first left that code unformatted until the next run. Fixer-inserted code is now formatted in the same run. The `--claude` and `--codex` agent passes follow the same order. `unicorn/no-nested-ternary` is now off in the oxlint and ESLint presets: its fixer adds parentheses that oxfmt and Prettier remove, so the two tools rewrote the file on every run. The core `no-nested-ternary` rule still reports nested ternaries. - [`8ddc078`](https://github.com/haydenbleasel/ultracite/commit/8ddc078): Enable three rules added in Stylelint 17 in the Stylelint preset: `selector-no-deprecated` and `selector-no-invalid` report selectors that CSS has dropped or that cannot parse, and `relative-selector-nesting-notation` is set to `explicit`, so nested relative selectors are written `& > b` rather than `> b`. The `property-layout-mappings`, `unit-layout-mappings` and `value-keyword-layout-mappings` rules are deliberately left off, since they reject every physical property, unit and keyword and can only autofix with a per-project `languageOptions.directionality` setting. The repo's own Stylelint lock is refreshed from 16.26.1 to 17.14.1, which the config packages already required; `ultracite init` already installs `stylelint@latest` so users are unaffected by the lock change. - [`4609d79`](https://github.com/haydenbleasel/ultracite/commit/4609d79): Update the vendored `anti-slop` Oxlint plugin to upstream v0.1.2 (commit `e8c4880`). The rule set is unchanged; this picks up a round of correctness fixes: `no-known-value-widening` now also reports known values passed into local `unknown`-typed type predicates, `no-object-parameters`, `no-unknown-parameters`, `no-unknown-returns` and `no-unknown-type-aliases` resolve scoped and transparent generic aliases (including block-scoped aliases and forward references), `no-unknown-returns` covers `PromiseLike<unknown>`, `no-unsafe-dictionary-type` allows generic constraints such as `T extends Record<string, unknown>`, `no-runtime-typeof` always allows existence probes against `"undefined"`, `no-shape-in-symbol-names` allows static member reads such as Zod's `schema.shape`, and `require-safety-comment-for-type-assertion` rejects empty justifications and gains a `markers` option (default `["SAFETY"]`). Upstream also added a separate opt-in `anti-slop-effect` plugin for Effect projects, which is not vendored. ### [`v7.10.7`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.10.7) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.10.6...ultracite@7.10.7) ##### Patch Changes - [`15f7ae0`](https://github.com/haydenbleasel/ultracite/commit/15f7ae0): Add support for the Aube package manager: `ultracite init --pm aube` is now accepted and projects with an `aube-lock.yaml` lockfile are detected automatically - [`1afc8fe`](https://github.com/haydenbleasel/ultracite/commit/1afc8fe): Re-declare selected Oxlint JS plugins on the root config so dependency analyzers see them. `ultracite init --linter oxlint --js-plugins ...` now generates `const jsPlugins = selectJsPlugins([...])` and adds `jsPlugins: jsPlugins.jsPlugins` to the root config (also when the full `ultracite/oxlint/js-plugins` preset is extended). Knip only resolves `jsPlugins` from the root Oxlint config and never walks `extends`, so `eslint-plugin-github`, `eslint-plugin-sonarjs`, and `oxlint-plugin-react-doctor` were reported as unused devDependencies. Oxlint dedupes the plugin between the root and the extended preset, so linting is unchanged. Also fix `ultracite update` dropping the `js-plugins` preset from `extends` when the config used the documented `import jsPlugins, { jsPluginSettings } from "ultracite/oxlint/js-plugins"` form: the import parser only matched bare default imports. The regenerated full-preset config keeps `settings: jsPluginSettings` on the root as well. - [`20b06bf`](https://github.com/haydenbleasel/ultracite/commit/20b06bf): Ignore `.alchemy` across all linters and formatters. Alchemy (alchemy.run) writes local state and generated bindings to a `.alchemy` directory. It is now part of the shared ignore patterns synced into Biome's `files.includes` and imported by oxlint, oxfmt, and ESLint, and the Stylelint preset ignores it via `ignoreFiles`. Prettier needs no change: it already respects `.gitignore`/`.prettierignore`. - [`6e9286c`](https://github.com/haydenbleasel/ultracite/commit/6e9286c): Run `lefthook install` during `ultracite init` through the same spawn adapter as every other tool invocation instead of `execSync`, so it no longer goes through a shell and gets the same Windows command resolution as `husky`, the linters, and editor extension installs. - [`8b24f34`](https://github.com/haydenbleasel/ultracite/commit/8b24f34): Add support for the Nub package manager: `ultracite init --pm nub` is now accepted and projects with a `nub.lock` lockfile are detected automatically (requires nypm ^0.6.9) - [`240cb6b`](https://github.com/haydenbleasel/ultracite/commit/240cb6b): Install into the workspace root correctly for Nub and Aube monorepos: nypm emits no root selector for them, so `nub add` ran without `-w` and was refused. Ultracite now hands nypm pnpm's flag set for these pnpm-compatible CLIs, producing `nub add --workspace-root --save-dev ultracite` - [`44ecbba`](https://github.com/haydenbleasel/ultracite/commit/44ecbba): Add Vitest type-test files (`**/*.{test-d,spec-d}.{ts,tsx,js,jsx}`) to the test-file globs so the shared test relaxations and the Vitest rule overrides apply to them, and enable the Vitest plugin's `typecheck` setting in the ESLint preset so `expectTypeOf`/`assertType` count as assertions. - [`7ba6bb8`](https://github.com/haydenbleasel/ultracite/commit/7ba6bb8): Package the reusable Ultracite agent skill with the npm distribution. ### [`v7.10.6`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.10.6) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.10.5...ultracite@7.10.6) ##### Patch Changes - [`972b946`](https://github.com/haydenbleasel/ultracite/commit/972b946): Update the oxlint presets for oxlint 1.79: replace the removed `react/react-compiler` rule with the 22 new React Compiler rules in the react preset, add `jsdoc/no-blank-blocks` and `one-var` to the core preset (mirrored in the ESLint presets), and require oxlint ^1.79.0 - [`2d5bbdb`](https://github.com/haydenbleasel/ultracite/commit/2d5bbdb): Declare the `jsPluginSettings` named export in the `ultracite/oxlint/js-plugins` type declarations, so the documented (and `ultracite init`-generated) `import jsPlugins, { jsPluginSettings } from "ultracite/oxlint/js-plugins"` type-checks ([#&#8203;773](https://github.com/haydenbleasel/ultracite/issues/773)) - [`56aef65`](https://github.com/haydenbleasel/ultracite/commit/56aef65): Refresh the toolchain versions that `ultracite init` installs into projects: `@biomejs/biome` 2.5.9, the ESLint plugin family (including eslint-plugin-cypress 7, eslint-plugin-jsdoc 64, eslint-plugin-solid 0.15, and eslint-plugin-unicorn 73 — the dynamic presets adopt their new rules automatically), and `prettier-plugin-svelte` 4.1.1 / `prettier-plugin-tailwindcss` 0.8.1 ### [`v7.10.5`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.10.5) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.10.4...ultracite@7.10.5) ##### Patch Changes - [`8df6ad0`](https://github.com/haydenbleasel/ultracite/commit/8df6ad0): Offer the vendored `anti-slop` Oxlint preset during `ultracite init` — it now appears in the JS-plugins prompt when you pick Oxlint, and non-interactive setup accepts it via `--js-plugins anti-slop`. Selecting it adds `ultracite/oxlint/anti-slop` to the generated config's `extends`; since the preset is vendored inside Ultracite, nothing extra is installed. - [`cd229e9`](https://github.com/haydenbleasel/ultracite/commit/cd229e9): Bump the `oxlint-plugin-react-doctor` pin from `^0.7.1` to `^0.9.12`, so `ultracite init` installs the current plugin. All react-doctor rules enabled by the js-plugins presets still exist in 0.9.12, and the ported rules run in curated mode via the settings shipped alongside this release ([#&#8203;771](https://github.com/haydenbleasel/ultracite/issues/771)). - [`e1ac886`](https://github.com/haydenbleasel/ultracite/commit/e1ac886): Pin React Doctor's ported rules to their framework-aware "curated" mode ([#&#8203;771](https://github.com/haydenbleasel/ultracite/issues/771)). react-doctor 0.9.x rewrote its ported oxc/react-refresh rules — notably `only-export-components` — with a stripped-down default mode: no framework detection, no route-file skipping, and `allowConstantExport` off, so Next.js route-segment exports like `export const dynamic = "force-static"` or `metadata` were flagged as non-component exports in every route file. The ESLint react preset now sets `settings["react-doctor"].portedRuleMode: "curated"`, and generated oxlint configs apply a new `jsPluginSettings` export from `ultracite/oxlint/js-plugins` on the root config (oxlint does not merge `settings` from extended configs, so the setting cannot ride along inside the preset). If you extend the js-plugins preset manually, add `settings: jsPluginSettings` to your root oxlint config. - [`c27fe36`](https://github.com/haydenbleasel/ultracite/commit/c27fe36): Generate oxlint configs that enable a subset of the JS plugins via a new `selectJsPlugins` export from `ultracite/oxlint/js-plugins`, instead of inlining the filtering logic into the generated file. The inlined block contained a `typeof` check that user-side lint presets flagged (`anti-slop/no-runtime-typeof`, [#&#8203;770](https://github.com/haydenbleasel/ultracite/issues/770)); the generated config is now a one-line extend, is emitted already formatted (including the previously missing blank line after imports), and re-running `ultracite init` migrates existing configs with the old inlined block automatically. - [`0616523`](https://github.com/haydenbleasel/ultracite/commit/0616523): Update the vendored `anti-slop` Oxlint plugin to upstream commit `446268e`, picking up fixes to `no-object-parameters` and `no-unknown-returns` (respect lexical type binders in alias resolution) and a new `allowInTypeGuards` option on `no-runtime-typeof`. The `ultracite/oxlint/anti-slop` preset enables `allowInTypeGuards`, so `typeof` checks inside type predicate functions (`(x): x is T`) no longer need disable comments — predicates are the named-boundary pattern the rule pushes toward ([dmmulroy/anti-slop#10](https://github.com/dmmulroy/anti-slop/issues/10)). ### [`v7.10.4`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.10.4) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.10.3...ultracite@7.10.4) ##### Patch Changes - [`417a85a`](https://github.com/haydenbleasel/ultracite/commit/417a85a): Add an opt-in `ultracite/oxlint/anti-slop` preset that ships a vendored, self-contained build of the [anti-slop](https://github.com/dmmulroy/anti-slop) Oxlint plugin — fifteen rules that reject low-evidence TypeScript and JavaScript patterns (unjustified type assertions, `unknown` leaking through signatures, `Reflect`-based access, module mocking, and more). Extend it alongside `ultracite/oxlint/core`; nothing extra to install. The preset also turns off two core rules that conflict with anti-slop's widening checks (`typescript/consistent-indexed-object-style` and `unicorn/no-immediate-mutation`) when extended after core. - [`4d3fab8`](https://github.com/haydenbleasel/ultracite/commit/4d3fab8): Move `suspicious/useArraySortCompare` from the Biome core config to the opt-in type-aware config. The rule is in Biome's `types` domain — it type-infers the receiver of every method call before checking the method name, which made `ultracite check` up to \~260x slower on projects with expensive library types (zod, better-auth, Prisma). It now only runs when type-aware linting is explicitly enabled, alongside the other type/project-domain rules. Fixes [#&#8203;768](https://github.com/haydenbleasel/ultracite/issues/768). ### [`v7.10.3`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.10.3) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.10.2...ultracite@7.10.3) ##### Patch Changes - [`a1fa9c4`](https://github.com/haydenbleasel/ultracite/commit/a1fa9c4): Replace the hand-rolled package `exports` map matching in the config-resolution doctor check with the resolve.exports library, which implements Node's full `PACKAGE_TARGET_RESOLVE` algorithm (wildcard patterns, key-order precedence, conditional exports, and array fallbacks). The manual `node_modules` walk is kept intentionally — it exists to avoid Bun's auto-install cache resolving specifiers the project's own `node_modules` can't. - [`414ea80`](https://github.com/haydenbleasel/ultracite/commit/414ea80): Replace the hand-rolled monorepo workspace scan in framework detection with the find-workspaces library. Workspace declarations from package.json (array and yarn-classic object form) and pnpm-workspace.yaml — including negated globs — are now resolved by the library instead of manual pattern collection and globbing, and lerna/bolt monorepos are picked up as well. - [`a9a1989`](https://github.com/haydenbleasel/ultracite/commit/a9a1989): Replace the hand-rolled upward directory walks in `findNearestFile` and `detectLinter` with the empathic library's `find.any`, which checks candidate names in order within each directory before moving to the parent — the same per-directory precedence the previous implementation enforced manually. - [`27b2707`](https://github.com/haydenbleasel/ultracite/commit/27b2707): Use magicast to update ESM lint-staged config files during `ultracite init`. The config is now edited as an AST instead of being imported and re-serialized, so comments and function-valued entries elsewhere in the config survive the update, and the user's config code is no longer executed. If the Ultracite glob pattern is already owned by a non-array value, or the config isn't a mergeable object literal (e.g. `defineConfig(...)`), init warns and leaves the file untouched instead of rewriting it. CommonJS configs keep the previous behavior. - [`f2529b8`](https://github.com/haydenbleasel/ultracite/commit/f2529b8): Rewrite the agent-fix progress renderer on top of log-update, cli-truncate, and string-width. log-update now owns the in-place block rewriting that was previously done with manual cursor-up/clear-line escape sequences, and line truncation is measured by display width instead of code units — so lint messages containing emoji or CJK text can no longer overflow the terminal row and corrupt the animated block. - [`277b9d6`](https://github.com/haydenbleasel/ultracite/commit/277b9d6): Replace the hand-rolled child-process handling in the agent fix runner with execa. The timeout → SIGTERM → grace period → SIGKILL escalation, stderr capture, and spawn-failure handling now use execa's `timeout` and `forceKillAfterDelay` options, which are battle-tested across platforms (including Windows kill semantics the manual implementation didn't cover). Behavior is unchanged: agent runs still time out after 5 minutes, escalate to SIGKILL after a 10-second grace period, and report a capped stderr tail. - [`1614a80`](https://github.com/haydenbleasel/ultracite/commit/1614a80): Drop the direct cross-spawn dependency: all synchronous process spawning (linter runs, tool version checks, editor extension installs, skill installs) now goes through a small adapter over execa's sync API, which owns the Windows spawn semantics cross-spawn provided. The adapter preserves the spawnSync result shape (`status`/`signal`/`error`/`stdout`), always disables shell interpretation, and always decodes output as UTF-8. execa was already a dependency for the agent fix runner, so this consolidates on one process-spawning library. - [`ac114b4`](https://github.com/haydenbleasel/ultracite/commit/ac114b4): Replace the glob dependency with fast-glob for the tsconfig.json scan during init. fast-glob was already in the dependency tree via find-workspaces, so this drops glob's transitive dependencies (minipass, path-scurry, etc.) from the install without changing behavior. ### [`v7.10.2`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.10.2) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.10.1...ultracite@7.10.2) ##### Patch Changes - [`1c48c68`](https://github.com/haydenbleasel/ultracite/commit/1c48c68): Enable Tailwind CSS class sorting (`sortTailwindcss`) in the Oxfmt preset. Classes in `class`/`className` attributes and in `clsx`, `cva`, `tw`, `twMerge`, `cn`, `twJoin`, and `tv` calls are now sorted using the same algorithm as `prettier-plugin-tailwindcss`, matching the behavior of the Prettier preset (which always loads the Tailwind plugin) and the Biome preset's `useSortedClasses` rule. Projects without Tailwind installed are unaffected beyond class strings being sorted against the default theme, and oxfmt versions older than 0.35.0 ignore the option. - [`dc78be4`](https://github.com/haydenbleasel/ultracite/commit/dc78be4): Stop sorting TanStack route option keys in route files. TanStack Router's route option types are order-sensitive (`head`/`component` infer `loaderData` from properties declared before them), so the Biome `useSortedKeys` source action rewrote `createFileRoute` literals into an order that breaks type inference (`loaderData` becomes `never`). The Biome TanStack preset now disables `useSortedKeys` for route files, and the oxlint TanStack preset disables `sort-keys` there so route files aren't caught between it and `react-doctor/tanstack-start-route-property-order`. ### [`v7.10.1`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.10.1) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.10.0...ultracite@7.10.1) ##### Patch Changes - [`d018b7f`](https://github.com/haydenbleasel/ultracite/commit/d018b7f): Fix several agent fix mode (`fix --claude`/`--codex`) issues: runs no longer abort with ENOBUFS when linter JSON output exceeds 1MB, user-supplied format/reporter flags can no longer override the JSON reporter and break parsing, a stuck agent process is force-killed 10 seconds after the timeout instead of hanging forever, and the progress renderer no longer garbles TTY output when file paths and rule names exceed the terminal width. - [`d018b7f`](https://github.com/haydenbleasel/ultracite/commit/d018b7f): Fix Biome config migration leaving the legacy bare `"extends": ["ultracite"]` form in place, which breaks Biome's module resolution since the package has no root export. It's now mapped to `ultracite/biome/core`. - [`d018b7f`](https://github.com/haydenbleasel/ultracite/commit/d018b7f): Fix `ultracite doctor` reporting spurious failures: config checks now walk up parent directories (matching `check`/`fix` and the linters themselves) so monorepo packages inheriting a root config pass, `.oxlintrc.json` is accepted as a valid oxlint config (with a migration suggestion), and Prettier/Stylelint configs declared via `package.json` keys are recognized. - [`d018b7f`](https://github.com/haydenbleasel/ultracite/commit/d018b7f): Fix `ultracite init` corrupting existing Prettier/Stylelint/ESLint configs by writing an ESM module into JSON/YAML/TOML/CJS config files (e.g. `.prettierrc`, `eslint.config.cjs`). Updates now write the default `.mjs` config instead and remove the incompatible file so it can't shadow the new one. - [`d018b7f`](https://github.com/haydenbleasel/ultracite/commit/d018b7f): Fix `ultracite check`/`fix` misrouting space-separated flag values (e.g. `--max-warnings 10`) into the file list, which scrambled the underlying linter invocation and made formatters fail on bogus targets. Positional files listed before a `--` separator are also kept as lint targets instead of being reclassified as passthrough, which could silently widen formatter runs to the whole project. - [`d018b7f`](https://github.com/haydenbleasel/ultracite/commit/d018b7f): Fix Lefthook and pre-commit YAML updates silently doing nothing on common config shapes: the Lefthook job is now inserted correctly when `jobs:` isn't the first key under `pre-commit:` (and no longer matches a `jobs:` key in a different hook), `repos: []` in `.pre-commit-config.yaml` is handled, and shapes that can't be safely edited produce a warning instead of writing the file back unchanged. - [`d018b7f`](https://github.com/haydenbleasel/ultracite/commit/d018b7f): Fix the Husky integration overwriting an existing `.husky/pre-commit` hook: `ultracite init` ran `husky init`, which unconditionally replaces the hook with `npm test`. It now runs plain `husky` to set up the hooks infrastructure without touching the hook file. - [`d018b7f`](https://github.com/haydenbleasel/ultracite/commit/d018b7f): Fix `ultracite init` destroying user files it couldn't parse or merge: unparseable `tsconfig.json` files are no longer replaced with a minimal config, unparseable `.vscode`/`.zed` settings are no longer overwritten wholesale, and lint-staged configs with function-valued entries are left untouched — all now warn and skip instead. - [`d018b7f`](https://github.com/haydenbleasel/ultracite/commit/d018b7f): Fix re-running `ultracite init` on an oxlint setup silently enabling the full js-plugins preset — the previously selected JS plugins are now preserved when no new selection is made. Init also no longer flips an explicit `"type": "commonjs"` in package.json to `"module"`; it warns instead. - [`d018b7f`](https://github.com/haydenbleasel/ultracite/commit/d018b7f): Fix switching linters removing `storybook` from the project's dependencies. It was swept into the removal set as a peer of `eslint-plugin-storybook`, but it's a user-facing tool a project may use independently of linting. - [`d018b7f`](https://github.com/haydenbleasel/ultracite/commit/d018b7f): Fix Stylelint target generation dropping directories with a dot in their name (e.g. `app.web`) and producing non-matching globs from Windows-style backslash paths. Framework detection also handles negated workspace patterns (`!packages/legacy`) again. - [`d018b7f`](https://github.com/haydenbleasel/ultracite/commit/d018b7f): Fix the CLI becoming a silent no-op (exiting 0 without linting anything) when a generic `TEST` environment variable is set, as is common in CI matrices. The internal test guard now uses `ULTRACITE_TEST`. - [`36c7b80`](https://github.com/haydenbleasel/ultracite/commit/36c7b80): Move [@&#8203;typescript-eslint/utils](https://github.com/typescript-eslint/utils) from dependencies to devDependencies. It was accidentally shipped as a runtime dependency in 7.9.0, pulling eslint and the typescript-eslint packages into every consumer's install (including oxlint-only setups) via npm's automatic peer dependency installation. Nothing in the published package imports it — it only exists to support the workspace-internal rule-parity script. ### [`v7.10.0`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.10.0) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.9.4...ultracite@7.10.0) ##### Minor Changes - [`cd0a36c`](https://github.com/haydenbleasel/ultracite/commit/cd0a36c): Add `--claude` and `--codex` flags to `ultracite fix`. After the normal autofix pass, remaining diagnostics are handed to the Claude Code or Codex CLI non-interactively, one agent run per affected file, with a live per-issue spinner that flips to ✓/✗ once the fix is verified by a re-lint. Fixes that don't survive verification are retried (up to 3 attempts per file) with the fresh diagnostics and feedback that the previous approach failed. Works with all three linter modes (Oxlint, Biome, ESLint); exits non-zero if any issues remain, matching the plain `fix` contract. - [`e089510`](https://github.com/haydenbleasel/ultracite/commit/e089510): Scope React Doctor's framework-specific rules to per-framework add-on presets ([#&#8203;752](https://github.com/haydenbleasel/ultracite/issues/752)) The `ultracite/oxlint/js-plugins` preset no longer enables React Doctor's `nextjs-*` and TanStack (`query-*`, `tanstack-start-*`) rules for every consumer. Rules like `nextjs-no-img-element` and `tanstack-start-no-anchor-element` fire on plain `<img>`/`<a>` JSX and recommend framework replacements, which falsely errored in Vite + React and other non-Next/non-TanStack projects. Those rules now live in two new add-on presets: - `ultracite/oxlint/next/js-plugins` - `ultracite/oxlint/tanstack/js-plugins` `ultracite init` wires the matching add-on automatically when you select the framework together with `oxlint-plugin-react-doctor`. If you manage `oxlint.config.ts` by hand and use Next.js or TanStack, add the matching add-on preset to `extends` alongside `js-plugins` to keep those rules — or re-run `npx ultracite init`. Also fixes re-running `init` on a config that already extends `js-plugins` producing a duplicate `import jsPlugins` declaration. ##### Patch Changes - [`3320cd8`](https://github.com/haydenbleasel/ultracite/commit/3320cd8): Update Biome to 2.5.6. No stable (non-nursery) rules were added, removed, or promoted between 2.5.3 and 2.5.6, so the preset configs are unchanged. - [`477cd6e`](https://github.com/haydenbleasel/ultracite/commit/477cd6e): Update ESLint to 10.8.0 and all ESLint plugins to their latest versions. Highlights: - `eslint-plugin-react-doctor` 0.9.3: the react preset expands from 149 to 417 rules, adopting the upstream `recommended` set (react-router, three.js/r3f, ink, motion, remotion, zustand/valtio/mobx, and more) while excluding rules that duplicate already-enabled `react`, `react-hooks`, and `jsx-a11y` rules. The next preset gains `nextjs-async-dynamic-api-not-awaited` and `nextjs-metadata-url-consistency`; the tanstack preset gains `tanstack-start-missing-scripts`, `query-floating-mutate-async`, and `query-no-mutation-in-effect-as-read`. - `eslint-plugin-unicorn` 72: adds `no-missing-local-resource`, `no-multiple-promise-resolver-calls`, `no-shorthand-property-overrides`, `no-transition-all`, `no-unnecessary-string-trim`, `no-useless-re-export`, `prefer-then-catch`, and `require-frontmatter-fields`. CSS-only rules are excluded from the preset since they fail config validation for JS files. - `eslint-plugin-sonarjs` 4.2: adds 11 rules including `no-fixed-wait-in-tests`, `parameterized-tests`, `assertions-in-test-cases`, `prefer-native-lodash-alternative`, and `explicit-test-skip`. - `typescript-eslint` 8.65: `@typescript-eslint/no-loop-func` and `@typescript-eslint/no-restricted-imports` were deprecated upstream in favor of the base rules, which now apply to TypeScript files. - `eslint-plugin-astro` 3: removes `astro/no-omitted-end-tags` and `astro/valid-compile`. - `eslint-plugin-svelte` 3.22: adds `no-bind-value-on-checkable-inputs` and `no-conflicting-module-names`; `no-restricted-html-elements` is now off because its schema requires a user-supplied element list. - `@angular-eslint/eslint-plugin` 22.1: adds `inject-at-top` and `prefer-service-decorator`. - [`b81578b`](https://github.com/haydenbleasel/ultracite/commit/b81578b): Fix the useSortedPackageJson action not being executed by turning on assist actions for package.json-like files. - [`9ec454a`](https://github.com/haydenbleasel/ultracite/commit/9ec454a): Update oxlint to 1.76.0 and oxfmt to 0.61.0. New stable rules added to the presets: `oxc/bad-match-all-arg`, `id-denylist`, `node/exports-style` (core), `react/function-component-definition` with arrow-function components (react), and `vitest/padding-around-test-blocks` (vitest). `node/no-top-level-await` is off — top-level await is idiomatic in ESM, Astro frontmatter, and build scripts — and the ESLint preset's `n/no-top-level-await` is now off to match. No rules were removed or promoted out of nursery. - [`ba61c02`](https://github.com/haydenbleasel/ultracite/commit/ba61c02): Fix generated oxlint.config.ts accessing plugin.name on ExternalPluginEntry without narrowing the string form, which caused a TypeScript error in projects that type-check the config ([#&#8203;753](https://github.com/haydenbleasel/ultracite/issues/753)) ### [`v7.9.4`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.9.4) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.9.3...ultracite@7.9.4) ##### Patch Changes - [`f480c12`](https://github.com/haydenbleasel/ultracite/commit/f480c12): Upgrade Biome to 2.5.3 to fix the LSP scanner deadlock ([#&#8203;10845](https://github.com/biomejs/biome/issues/10845)) where editors get stuck on "Biome is scanning the project". - [`1d70c40`](https://github.com/haydenbleasel/ultracite/commit/1d70c40): Fail fast with an actionable message when Biome can't resolve `ultracite/biome/core`. Biome resolves that config out of the project's `node_modules`, so it errors with an opaque "module not found" whenever Ultracite isn't installed there — a state `npx ultracite check` / `bunx ultracite check` hide, because they run the CLI from a temp cache regardless. `check` and `fix` now detect it before invoking Biome and say what's actually wrong, and `doctor` verifies that Ultracite resolves rather than just appearing in `package.json` ([#&#8203;750](https://github.com/haydenbleasel/ultracite/issues/750)). - [`38d10bc`](https://github.com/haydenbleasel/ultracite/commit/38d10bc): Move Biome's `noUnknownAttribute` rule out of the core preset and into the `react` preset. The rule only recognises React's JSX attribute names, so projects using Solid, Svelte, Vue, or Qwik were incorrectly flagged for framework-standard attributes such as `class`. - [`cf723bd`](https://github.com/haydenbleasel/ultracite/commit/cf723bd): Add interactive and non-interactive selection for optional Oxlint JS plugins during init. ### [`v7.9.3`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.9.3) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.9.2...ultracite@7.9.3) ##### Patch Changes - [`dc6d760`](https://github.com/haydenbleasel/ultracite/commit/dc6d760): Disable the `n/no-unpublished-import` rule in the ESLint core config. This rule flags imports of packages that aren't listed as published dependencies, but it produces a lot of false positives in practice, so it's now turned off. - [`15ecfba`](https://github.com/haydenbleasel/ultracite/commit/15ecfba): Fix `ultracite init --linter eslint` installing an unusable toolchain. The generated ESLint config imports `eslint-plugin-storybook` unconditionally (which requires the `storybook` peer) and the generated Stylelint config extends `stylelint-config-standard` / `stylelint-config-idiomatic-order` / `stylelint-prettier`, but none of those packages were installed — so a fresh ESLint setup failed to load with "Cannot find package 'storybook'" or "Could not find stylelint-config-standard". These four packages are now installed with the ESLint linter. - [`2f73a41`](https://github.com/haydenbleasel/ultracite/commit/2f73a41): Upgrade to oxlint 1.73.0 and oxfmt 0.58.0, and enable the new lint rules they introduce: `no-unreachable-loop`, `unicorn/explicit-timer-delay`, and `unicorn/no-confusing-array-with`. - [`83b2783`](https://github.com/haydenbleasel/ultracite/commit/83b2783): Add an `[astro]` formatter mapping (`astro-build.astro-vscode`) to the oxlint VS Code editor settings generated by `ultracite init`, since oxfmt doesn't format `.astro` files. - [`d186c53`](https://github.com/haydenbleasel/ultracite/commit/d186c53): Move every JS-plugin-based rule set out of the Oxlint core and framework presets and into a single opt-in `ultracite/oxlint/js-plugins` preset. This covers `eslint-plugin-github` and `eslint-plugin-sonarjs` (previously in core) as well as `oxlint-plugin-react-doctor` (previously bundled into the `react`, `next`, and `tanstack` presets). The core, `react`, `next`, and `tanstack` presets now run entirely on Oxlint's native Rust rules, so new setups no longer install those dependencies and no longer pay the slower JS-plugin lint pass. To keep the extra ESLint-parity and React Doctor rules, install `eslint-plugin-github`, `eslint-plugin-sonarjs`, and `oxlint-plugin-react-doctor` and extend `ultracite/oxlint/js-plugins` alongside `core` (and your framework preset). - [`057753e`](https://github.com/haydenbleasel/ultracite/commit/057753e): Add performance benchmarks for `ultracite check` / `ultracite fix` across all three providers (oxlint, biome, eslint). A new CI job builds the PR and its base branch on the same runner, benchmarks them interleaved, and fails on a statistically significant regression (median ratio > 1.25x with Mann-Whitney U p < 0.05) so config changes can't silently slow the linters down again. ### [`v7.9.2`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.9.2) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.9.1...ultracite@7.9.2) ##### Patch Changes - [`c335a1f`](https://github.com/haydenbleasel/ultracite/commit/c335a1f): Add `**/node_modules` and `**/.git` to the shared ignore patterns. oxlint only skips `node_modules` when a `.gitignore` lists it, so in projects without one, `ultracite fix` would lint and autofix files inside `node_modules` — corrupting installed packages (e.g. rewriting `var` enum wrappers in `typescript/lib/typescript.js` to self-referencing `const`, causing "Cannot access 'Comparison' before initialization" when oxlint loads eslint-plugin-sonarjs). Fixes [#&#8203;737](https://github.com/haydenbleasel/ultracite/issues/737). ### [`v7.9.1`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.9.1) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.9.0...ultracite@7.9.1) ##### Patch Changes - [`ecd10cc`](https://github.com/haydenbleasel/ultracite/commit/ecd10cc): Disable `sonarjs/no-implicit-dependencies` and `github/no-implicit-buggy-globals` in the oxlint and ESLint presets. Both produce false positives through oxlint's JS plugin bridge: `no-implicit-dependencies` has no dependency-manifest resolution so it flags builtin (`bun:test`) and workspace imports as missing dependencies, and `no-implicit-buggy-globals` misreads module-scoped declarations such as Astro frontmatter as implicit globals. - [`c76f59d`](https://github.com/haydenbleasel/ultracite/commit/c76f59d): Disable `sonarjs/file-name-differ-from-class` in the oxlint and ESLint presets. It fires on any file whose name differs from an exported class, which is noise for the many config and module files that export objects rather than classes. - [`29e30ce`](https://github.com/haydenbleasel/ultracite/commit/29e30ce): Fold the github and sonarjs rules into the oxlint core preset. The standalone `ultracite/oxlint/github` and `ultracite/oxlint/sonarjs` presets are removed — ultracite ships framework presets, not individual plugins. Their rules now live in `ultracite/oxlint/core`, so every oxlint setup gets eslint-plugin-github and eslint-plugin-sonarjs through oxlint's JS plugin bridge, matching how the ESLint preset already bundles them into core. This is a breaking change to generated configs: `ultracite/oxlint/github` and `ultracite/oxlint/sonarjs` no longer exist. Re-run `ultracite init` to regenerate `oxlint.config.ts`. Also fixed: nine sonarjs rules (`async-test-assertions`, `hooks-before-test-cases`, `no-duplicate-test-title`, `no-empty-test-title`, `no-floating-point-equality`, `no-forced-browser-interaction`, `no-trivial-assertions`, `prefer-specific-assertions`, `super-linear-regex`) that exist in eslint-plugin-sonarjs but that oxlint's JS plugin bridge does not register. Naming them made oxlint hard-fail config parsing, which broke `ultracite fix`/`check` for oxlint projects using the sonarjs preset. They are omitted from oxlint core (still enabled in the ESLint preset), and a test now runs oxlint against core to catch this class of regression. The React Doctor, github, and sonarjs plugins are installed into your project's devDependencies at init (as the ESLint plugins already were), rather than bundled as dependencies of ultracite — oxlint resolves JS plugin specifiers from the project root, so they must be installed there directly. - [`8a4291f`](https://github.com/haydenbleasel/ultracite/commit/8a4291f): Upgrade to Oxlint 1.72.0 and Oxfmt 0.57.0. Oxfmt 0.57 adds native CSS and GraphQL formatters. The five new non-nursery Oxlint rules from the 1.71/1.72 releases are already covered by the presets (`node/no-sync`, `node/no-mixed-requires`, `unicorn/prefer-number-coercion`, `unicorn/max-nested-calls`, `vue/no-async-in-computed-properties`). The markdown `:::` container-directive fence patch (which keeps `proseWrap: "never"` from folding fences into prose) was regenerated against the 0.57 bundle. ### [`v7.9.0`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.9.0) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.8.4...ultracite@7.9.0) ##### Minor Changes - [`aea7fc0`](https://github.com/haydenbleasel/ultracite/commit/aea7fc0): Update Biome to 2.5.2 and enable the newly-stabilized rules. This adds coverage for the rules promoted out of nursery in Biome 2.5.0, including `noShadow`, `noUnnecessaryConditions`, `noUnusedInstantiation` (formerly `noFloatingClasses`), `useArrayFind`, `useDestructuring`, `useGlobalThis`, `useErrorCause`, `noNestedPromises`, GraphQL validation rules, and the recommended Vue/Next.js domain rules. - [`2687cf9`](https://github.com/haydenbleasel/ultracite/commit/2687cf9): Align the ESLint and Biome presets with the oxlint preset, which is now the benchmark for rule decisions across linters. ESLint: rules that oxlint deliberately disables are now off (`no-console`, `no-continue`, `id-length`, `new-cap`, `max-depth`, `no-implicit-coercion`, `no-underscore-dangle`, `init-declarations`, `n/no-sync`, `promise/always-return`, `promise/catch-or-return`, `import-x/no-commonjs`, `import-x/no-dynamic-require`, `import-x/no-nodejs-modules`, `import-x/unambiguous`, `import-x/no-anonymous-default-export`, `@typescript-eslint/explicit-member-accessibility`, `@typescript-eslint/explicit-module-boundary-types`, `@typescript-eslint/no-require-imports`, and the `unicorn` rules `explicit-length-check`, `max-nested-calls`, `no-process-exit`, `prefer-global-this`, `prefer-string-raw`, `prefer-top-level-await`); `consistent-type-definitions` now enforces `interface` instead of `type`, matching oxlint and Biome; `no-void` allows statement position to coexist with `no-floating-promises`; `import-x/no-named-as-default` is enabled; and `curly` and `no-unexpected-multiline` are re-enabled past `eslint-config-prettier`. Biome: `noAwaitInLoops` and `noIncrementDecrement` are now errors and the `useSortedKeys` assist is on (matching `no-await-in-loop`, `no-plusplus`, and `sort-keys` in the other presets), while `useGlobalThis` is off (matching `unicorn/prefer-global-this`). - [`73c1993`](https://github.com/haydenbleasel/ultracite/commit/73c1993): Require ESLint 10 for ESLint setups. The plugin suite upgrade (notably `eslint-plugin-unicorn` 70 and `eslint-plugin-astro` 2) requires ESLint 10, but `ultracite init` still installed `eslint@^9.0.0`, which crashed at config load time. Init now installs `eslint@^10.0.0` and `@eslint/js@^10.0.0`, and the presets are fixed for ESLint 10 compatibility: `settings.react.version` is pinned to `19.0.0` instead of `"detect"` (detection uses an API removed in ESLint 10), `react/jsx-filename-extension` and `react/forward-ref-uses-ref` are disabled (their implementations use removed APIs; the former is already off in the oxlint preset and the latter is covered by `react-doctor/no-react19-deprecated-apis`), the react config re-applies `eslint-config-prettier` so JSX formatting rules stay off (several crash under ESLint 10), and `import-x/no-unused-modules` is disabled (it is a warning-emitting no-op under ESLint 10). Note that some plugins (`eslint-plugin-github`, `eslint-plugin-react`, `eslint-plugin-jsx-a11y`, `eslint-plugin-solid`, `@tanstack/eslint-plugin-start`) have not yet updated their declared peer ranges to include ESLint 10 even though they work at runtime, so strict package managers may report peer dependency warnings. - [`4cfdf3d`](https://github.com/haydenbleasel/ultracite/commit/4cfdf3d): Add `eslint-plugin-jsdoc` to the ESLint preset. The oxlint preset already enforces a set of jsdoc rules, but the ESLint preset had no jsdoc coverage at all. The plugin is now installed by `ultracite init` for ESLint setups and enables the same rule selection the oxlint preset enforces (`check-access`, `check-property-names`, `check-tag-names`, `empty-tags`, `implements-on-classes`, `no-defaults`, and the `require-*` description/name/type rules), keeping the two presets in lockstep. - [`0b8fc12`](https://github.com/haydenbleasel/ultracite/commit/0b8fc12): Upgrade the ESLint plugin suite and enable the new rules that ship with it. Notable bumps: `eslint-plugin-unicorn` 64 → 70 (adds a large batch of new correctness and quality rules), `eslint-plugin-astro` 1 → 2 (adds `no-omitted-end-tags`, now requires ESLint 10), `eslint-plugin-sonarjs` 4.0 → 4.1 (adds test-assertion and ReDoS rules like `super-linear-regex`), `eslint-plugin-svelte` 3.19 → 3.20 (adds `no-at-const-tags`), plus `@typescript-eslint`, `eslint-plugin-import-x`, `eslint-plugin-n`, `@vitest/eslint-plugin`, and others. Two Unicorn rules that were renamed are re-mapped in the config (`prefer-dom-node-dataset` → `dom-node-dataset`, `prevent-abbreviations` → `name-replacements`). Two new Unicorn rules are disabled: `prefer-temporal` (since `Temporal` still lacks broad runtime support) and `no-asterisk-prefix-in-documentation-comments` (it fights the conventional JSDoc comment style). - [`4440393`](https://github.com/haydenbleasel/ultracite/commit/4440393): Bring the oxlint preset closer to ESLint parity with two new presets that run ESLint plugins through oxlint's JS plugin support: `ultracite/oxlint/github` (eslint-plugin-github) and `ultracite/oxlint/sonarjs` (eslint-plugin-sonarjs, 187 rules — type-aware rules are excluded since the JS plugin bridge provides no type information, and `no-reference-error` is off because the bridge provides no globals). `ultracite init` now adds both presets to generated oxlint configs and installs the two plugins; existing configs are untouched until the next `init`, and either preset can be dropped from `extends` to opt out (the plugins add roughly 1–3s to a lint run for the JS runtime bridge). Rule decisions mirror the oxlint benchmark in both directions: the ESLint preset now disables `sonarjs/file-header` (it errored on every file), `sonarjs/arrow-function-convention` (fights the formatter), `sonarjs/cyclomatic-complexity`, `sonarjs/max-lines`, `sonarjs/max-lines-per-function`, `sonarjs/nested-control-flow` (duplicates of core rules the preset disables), `sonarjs/shorthand-property-grouping` (conflicts with `sort-keys`), and `github/no-dataset` (conflicts with `unicorn/prefer-dom-node-dataset`), and sets `sonarjs/cognitive-complexity` to 20 to match Biome's `noExcessiveCognitiveComplexity`. Switching linters with `init` no longer removes dependencies that the newly selected linter still needs. - [`f7025b1`](https://github.com/haydenbleasel/ultracite/commit/f7025b1): Extend cross-linter parity to the framework presets and add an automated parity check. The oxlint react preset now explicitly lists all 102 non-nursery react/react-perf/jsx-a11y rules (previously only \~20 were configured, so most a11y and correctness rules silently never ran) and the next preset lists all 21 nextjs rules, with decisions matching the ESLint presets. The revived exhaustiveness test (the `oxlint --rules` markdown output it parsed is empty as of oxlint 1.72, so it was passing vacuously) also caught five newly stabilized rules which are now enabled: `getter-return`, `no-unreachable`, `oxc/branches-sharing-code`, `unicorn/prefer-export-from`, and `unicorn/prefer-single-call`. ESLint preset fixes that fell out of the audit: `no-loss-of-precision` and `no-duplicate-imports` are re-enabled for TypeScript files (their `@typescript-eslint` twins were removed in v8, leaving TS uncovered), `no-duplicate-imports` gets `allowSeparateTypeImports` to match oxlint, the react/vue configs now only re-apply the `react/`-`vue/`-prefixed entries of `eslint-config-prettier` so they can't clobber unrelated rules, the svelte preset keeps the formatting rules disabled that `eslint-plugin-svelte`'s own prettier preset lists, and `astro/semi` is off (Prettier owns formatting). A new `compare-rule-parity` script runs as part of `validate:configs`: it resolves the effective ESLint rule sets with ESLint's own config resolution, normalizes names to oxlint's, and fails on any divergence not recorded in an explicit allowlist — currently just two entries (`sonarjs/no-reference-error`, `unicorn/number-literal-case`), both with documented reasons. - [`223233f`](https://github.com/haydenbleasel/ultracite/commit/223233f): Add [React Doctor](https://www.react.doctor) rules to the ESLint and Oxlint React, Next.js, and TanStack presets. This enables React Doctor's own rules — the "You Might Not Need an Effect" family (`no-fetch-in-effect`, `no-derived-state`, `no-mirror-prop-effect`, etc.) plus its render-performance, hydration, server-component, security, and framework-specific rules — via `eslint-plugin-react-doctor` and the `oxlint-plugin-react-doctor` JS plugin. Rules that React Doctor ports from `eslint-plugin-react`, `eslint-plugin-react-hooks`, and `eslint-plugin-jsx-a11y` are intentionally left off to avoid duplicate diagnostics with the plugins Ultracite already ships. ##### Patch Changes - [`d247ff2`](https://github.com/haydenbleasel/ultracite/commit/d247ff2): Migrate stale linter and formatter configuration when switching toolchains during init. Running `ultracite init` now removes config files and dependencies for unselected Biome, ESLint/Prettier/Stylelint, or Oxlint/Oxfmt setups before writing the selected toolchain config. - [`e24068b`](https://github.com/haydenbleasel/ultracite/commit/e24068b): Sort `package.json` keys when using Biome ### [`v7.8.4`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.8.4) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.8.3...ultracite@7.8.4) ##### Patch Changes - [`e4ddd22`](https://github.com/haydenbleasel/ultracite/commit/e4ddd22): Ignore `.yarn` directories by default - [`a1d5c06`](https://github.com/haydenbleasel/ultracite/commit/a1d5c06): Configure Oxfmt to never wrap prose (`proseWrap: "never"`) - [`df709a4`](https://github.com/haydenbleasel/ultracite/commit/df709a4): Ignore `.wrangler` and `.wrangler-dry-run` output directories by default ### [`v7.8.3`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.8.3) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.8.2...ultracite@7.8.3) ##### Patch Changes - [`c863d09`](https://github.com/haydenbleasel/ultracite/commit/c863d09): Fix automatic editor extension installation during `ultracite init`. The whole command line (e.g. `code --install-extension`) was passed to `spawnSync` as the executable name, which always failed with `ENOENT` and silently fell back to the "install manually" message. The command is now split into the binary and its arguments, so the linter extension actually installs for VS Code-based editors. - [`6888129`](https://github.com/haydenbleasel/ultracite/commit/6888129): Enable the `eslint/no-await-in-loop` rule as an error in the core Oxlint preset. Awaiting inside a loop forces each iteration to run sequentially, which can lead to serious performance issues when the asynchronous operations could otherwise run concurrently. Promoting this rule to an error encourages collecting promises and resolving them together (e.g. with `Promise.all`) instead of blocking on each one in turn. - [`62a9b5c`](https://github.com/haydenbleasel/ultracite/commit/62a9b5c): Fix the generated Husky pre-commit hook's error handling and section replacement. The standalone hook script set `set -e` and then tried to capture the formatter's exit code, re-stage files, and print a failure message — but a non-zero formatter exit terminated the script immediately, so none of that ever ran. The script now captures the exit code with `|| FORMAT_EXIT_CODE=$?` so files are re-staged and failures are reported with the right exit code. Re-running `ultracite init` also deleted everything from the `# ultracite` marker to the end of the hook, including commands the user added after the ultracite section. The section is now terminated with an explicit `# ultracite end` marker and updates replace only the section between the markers (legacy sections without an end marker are detected by their closing echo line). - [`6608ceb`](https://github.com/haydenbleasel/ultracite/commit/6608ceb): Make the lint-staged integration idempotent and respect dedicated config files. `package.json` was always treated as the lint-staged config because the file exists in every project, so `ultracite init` wrote the lint-staged config into `package.json` even when a dedicated `.lintstagedrc.*` or `lint-staged.config.*` file was present — leaving two conflicting configs. `package.json` now only counts when it actually has a `lint-staged` key; otherwise the dedicated config file is updated (or `.lintstagedrc.json` is created). Re-running `ultracite init` also appended another `npx ultracite fix` entry on every run because the merge concatenates arrays. Updates are now skipped when the existing config already references ultracite. - [`4e847f7`](https://github.com/haydenbleasel/ultracite/commit/4e847f7): Insert `--` before script arguments in npm hook commands. The post-edit hook command generated for npm projects was `npm run fix --skip=correctness/noUnusedImports`, where npm consumes the `--skip` flag itself instead of forwarding it to the script — so agent hooks ran a plain `ultracite fix`, including the unused-import removal the flag exists to prevent mid-edit. The generated command is now `npm run fix -- --skip=correctness/noUnusedImports`, matching the documented form. - [`ecb0d5b`](https://github.com/haydenbleasel/ultracite/commit/ecb0d5b): Scope the Stylelint step of `ultracite check` and `ultracite fix` (ESLint mode) to style files. Stylelint was previously given the same targets as ESLint and Prettier (or `.` when no files were passed), so it tried to parse `.ts`/`.json` files as CSS and failed with `CssSyntaxError`. Style files now pass through unchanged, directory targets become `**/*.{css,scss,sass,less}` globs, other files are dropped, and the step is skipped entirely when no style targets remain. `--allow-empty-input` is passed so projects without CSS still succeed. - [`61ea0a1`](https://github.com/haydenbleasel/ultracite/commit/61ea0a1): Fix the project-path write guard's error message and ordering. The "Refusing to write through directory outside project" error interpolated the `node:path` module instead of the offending file path, printing `[object Object]`. It now reports the actual path. `writeProjectFile` also created directories (`mkdir -p`) before running the path-escape check, so directories could be created outside the project before the guard threw. Validation now happens first; the parent-directory check resolves the nearest existing ancestor so writes into not-yet-created nested directories still work. ### [`v7.8.2`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.8.2) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.8.1...ultracite@7.8.2) ##### Patch Changes - [`30971a8`](https://github.com/haydenbleasel/ultracite/commit/30971a8): Enable newly available Oxlint and Stylelint rules in the shared configs. For Oxlint, the core preset now enables `eslint/prefer-named-capture-group`, `jsdoc/require-yields-description`, `node/callback-return`, `typescript/method-signature-style`, and `unicorn/import-style`. The Vue preset now enables `vue/component-definition-name-casing`, `vue/no-computed-properties-in-data`, `vue/no-deprecated-props-default-this`, `vue/no-expose-after-await`, `vue/no-reserved-component-names`, `vue/no-shared-component-data`, `vue/no-watch-after-await`, `vue/require-prop-type-constructor`, `vue/require-render-return`, `vue/require-slots-as-functions`, `vue/return-in-emits-validator`, `vue/valid-define-options`, and `vue/valid-next-tick`. The Stylelint preset now enables `display-notation` with the `short` option. ### [`v7.8.1`](https://github.com/haydenbleasel/ultracite/releases/tag/ultracite%407.8.1) [Compare Source](https://github.com/haydenbleasel/ultracite/compare/ultracite@7.8.0...ultracite@7.8.1) ##### Patch Changes - [`8335be7`](https://github.com/haydenbleasel/ultracite/commit/8335be7): Build the CLI with `bun build` and a `tsgo` type-check gate instead of tsup. - [`f747449`](https://github.com/haydenbleasel/ultracite/commit/f747449): Fix the Oxlint TanStack preset so route files under `routes/` and `app/routes/` are exempt from `unicorn/filename-case`, matching the documented 7.8.0 behavior. - [`092597e`](https://github.com/haydenbleasel/ultracite/commit/092597e): Fix generated `oxlint.config.ts` to be pre-formatted according to oxfmt rules, so `ultracite check` passes immediately after `ultracite init` without requiring a separate format step. - [`81da6e8`](https://github.com/haydenbleasel/ultracite/commit/81da6e8): Generate agent and editor hook commands through nypm's package-manager script helper. - [`81da6e8`](https://github.com/haydenbleasel/ultracite/commit/81da6e8): Keep hyphen-prefixed file operands from being forwarded to linters as options. </details> <details> <summary>astral-sh/uv (uv_build)</summary> ### [`v0.12.13`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#01213) [Compare Source](https://github.com/astral-sh/uv/compare/0.12.12...0.12.13) Released on 2026-09-10. ##### Python - Add GraalPy 3.13.0 ([#&#8203;21431](https://github.com/astral-sh/uv/pull/21431)) ##### Enhancements - Verify hashes when downloading PEP 658 metadata sidecars ([#&#8203;21563](https://github.com/astral-sh/uv/pull/21563)) ##### Preview features - Respect `ty` exclusions when `uv check` automatically selects members of a virtual workspace ([#&#8203;21555](https://github.com/astral-sh/uv/pull/21555)) ##### Performance - Avoid full wheel downloads during resolution by reusing supported hashes from direct URL fragments when metadata is available separately ([#&#8203;21279](https://github.com/astral-sh/uv/pull/21279)) ##### Bug fixes - Edit Windows entry-point launcher resources in memory to support Nano Server and reduce antivirus contention ([#&#8203;18713](https://github.com/astral-sh/uv/pull/18713)) - Prefer `core-metadata` over legacy aliases in JSON index responses ([#&#8203;21563](https://github.com/astral-sh/uv/pull/21563)) ### [`v0.12.12`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#01212) [Compare Source](https://github.com/astral-sh/uv/compare/0.12.11...0.12.12) Released on 2026-09-09. The executables in our macOS and Windows release archives and `uv` and `uv_build` wheels are now code-signed. macOS executables are signed with an Apple Developer ID certificate and notarized by Apple. Windows executables have timestamped Authenticode signatures from Azure Artifact Signing. This enables verification of the release publisher and binary integrity, supports publisher-based allowlisting, and should reduce security warnings and antivirus false positives. ##### Bug fixes - Exclude distributions uploaded after the `exclude-newer` cutoff from lockfiles and generated requirement hashes ([#&#8203;21539](https://github.com/astral-sh/uv/pull/21539)) ### [`v0.12.11`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#01211) [Compare Source](https://github.com/astral-sh/uv/compare/0.12.10...0.12.11) Released on 2026-09-08. ##### Preview features - Generate missing artifact hashes when exporting `pylock.toml` files to ensure they conform to PEP 751 ([#&#8203;20146](https://github.com/astral-sh/uv/pull/20146)) - Warn when `pylock.toml` artifact hash tables are empty, which will be rejected in a future uv release ([#&#8203;21462](https://github.com/astral-sh/uv/pull/21462)) ##### Performance - Speed up installs that overwrite existing files by eliminating per-file temporary directories for atomic hard-link, symlink, and reflink replacements ([#&#8203;21478](https://github.com/astral-sh/uv/pull/21478)) - Speed up installs that merge copied wheels into existing environments by replacing per-file temporary directories with adjacent temporary files ([#&#8203;21468](https://github.com/astral-sh/uv/pull/21468)) - Speed up local wheel installs by replacing the shared ZIP cursor lock with positioned reads ([#&#8203;21500](https://github.com/astral-sh/uv/pull/21500)) - Speed up local wheel installs by reusing ZIP readers and buffers across extracted files ([#&#8203;21499](https://github.com/astral-sh/uv/pull/21499)) - Avoid transitive dependency checks and unnecessary resolution when `uv pip install --no-deps` finds the requested packages already installed ([#&#8203;21523](https://github.com/astral-sh/uv/pull/21523)) ##### Bug fixes - Verify source archives against hashes recorded in `uv.lock` before reading their metadata or running their build backends ([#&#8203;21223](https://github.com/astral-sh/uv/pull/21223)) - Verify supplied hashes for registry requirements pinned with `===` under both `--verify-hashes` and `--require-hashes` ([#&#8203;21543](https://github.com/astral-sh/uv/pull/21543)) - Apply hashes from public-version pins to matching local versions when no exact local-version hash is provided ([#&#8203;21544](https://github.com/astral-sh/uv/pull/21544)) - Support PowerShell virtual environment activation from UNC paths, including WSL paths ([#&#8203;19159](https://github.com/astral-sh/uv/pull/19159)) - Trim surrounding whitespace from entries in `.python-version` and `.python-versions` files ([#&#8203;21529](https://github.com/astral-sh/uv/pull/21529)) - Suppress `VIRTUAL_ENV` mismatch warnings for `uv add --no-sync`, `uv remove --no-sync`, and `uv add --frozen` ([#&#8203;21496](https://github.com/astral-sh/uv/pull/21496)) - Warn and continue when `uv python list` cannot query an interpreter ([#&#8203;21498](https://github.com/astral-sh/uv/pull/21498)) ##### Documentation - Restore TOML syntax highlighting for `exclude-newer` examples ([#&#8203;21534](https://github.com/astral-sh/uv/pull/21534)) ### [`v0.12.10`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#01210) [Compare Source](https://github.com/astral-sh/uv/compare/0.12.9...0.12.10) Released on 2026-09-04. ##### Enhancements - Attempt to revoke short-lived PyPI trusted-publishing tokens after `uv publish` completes, including when publishing fails ([#&#8203;21423](https://github.com/astral-sh/uv/pull/21423)) ##### Preview features - Omit `exclude-newer-package` settings for packages outside the resolution from `uv.lock` with the `missing-exclude-newer-package-lock` preview feature ([#&#8203;21455](https://github.com/astral-sh/uv/pull/21455)) - Show terminal dependency cycles in `uv tree --invert` output ([#&#8203;21404](https://github.com/astral-sh/uv/pull/21404)) ##### Performance - Speed up locking large workspaces with conflicts by excluding unrelated extras and dependency groups from conflict simplification ([#&#8203;21399](https://github.com/astral-sh/uv/pull/21399)) - Speed up `uv publish` by hashing each artifact in a single blocking task and reusing the buffer across reads ([#&#8203;21389](https://github.com/astral-sh/uv/pull/21389)) ##### Bug fixes - Prevent `--locked` from failing when `exclude-newer-package` settings differ only for packages outside the resolution ([#&#8203;21454](https://github.com/astral-sh/uv/pull/21454)) - Allow `uv lock --check` to reuse a lockfile when an absolute `exclude-newer` cutoff is moved later ([#&#8203;19571](https://github.com/astral-sh/uv/pull/19571)) - Allow `uv lock --check` to reuse a lockfile when a package-specific `exclude-newer` cutoff is disabled ([#&#8203;21450](https://github.com/astral-sh/uv/pull/21450)) - Require an explicit `--name` when `uv init` would infer a project name reserved for a Python interpreter ([#&#8203;21395](https://github.com/astral-sh/uv/pull/21395)) - Write package-specific `exclude-newer` cutoffs to `uv.lock` in a deterministic order ([#&#8203;21453](https://github.com/astral-sh/uv/pull/21453)) ### [`v0.12.9`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0129) [Compare Source](https://github.com/astral-sh/uv/compare/0.12.8...0.12.9) Released on 2026-09-01. ##### Python - Add CPython 3.15.0rc2 ([#&#8203;21413](https://github.com/astral-sh/uv/pull/21413), [#&#8203;21415](https://github.com/astral-sh/uv/pull/21415)) ##### Enhancements - Add `--no-locked` and `--no-frozen` to disable lock modes enabled by `UV_LOCKED` and `UV_FROZEN` for a single invocation ([#&#8203;21408](https://github.com/astral-sh/uv/pull/21408)) - Report the exact command-line lock-mode flag in warnings and errors ([#&#8203;21402](https://github.com/astral-sh/uv/pull/21402)) ##### Performance - Speed up cold wheel installs by extracting each streaming ZIP archive in a single blocking task and reusing buffers across files ([#&#8203;21372](https://github.com/astral-sh/uv/pull/21372)) ##### Bug fixes - Update `async_http_range_reader` to 0.11.1 to address a potential memory-safety issue when reading metadata ranges from untrusted wheels ([#&#8203;21401](https://github.com/astral-sh/uv/pull/21401)) - Remove sensitive headers when redirects cross authentication realms, including same-host redirects that change URL schemes ([#&#8203;21382](https://github.com/astral-sh/uv/pull/21382)) - Redact secrets in signed URLs from retry diagnostics, including nested request errors ([#&#8203;21381](https://github.com/astral-sh/uv/pull/21381)) - Give `--locked`, `--frozen`, `--check`, and `--check-exists` precedence over conflicting `UV_LOCKED` and `UV_FROZEN` values ([#&#8203;21396](https://github.com/astral-sh/uv/pull/21396)) - Prevent concurrent uv processes from redundantly extracting the same local or source-built wheel ([#&#8203;21400](https://github.com/astral-sh/uv/pull/21400)) ### [`v0.12.8`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0128) [Compare Source](https://github.com/astral-sh/uv/compare/0.12.7...0.12.8) Released on 2026-08-31. ##### Enhancements - Warn about invalid tool directories and continue upgrading valid tools with `uv tool upgrade --all` ([#&#8203;21368](https://github.com/astral-sh/uv/pull/21368)) ##### Preview features - Deduplicate identical files within and across cached wheels with the `content-addressed-cache` preview feature ([#&#8203;21327](https://github.com/astral-sh/uv/pull/21327)) - Reduce allocations while extracting content-addressed wheels by reusing the hashing buffer across files ([#&#8203;21340](https://github.com/astral-sh/uv/pull/21340)) - Speed up content-addressed cache cleanup on macOS by reading hard-link counts in bulk ([#&#8203;21344](https://github.com/astral-sh/uv/pull/21344)) ##### Performance - Prevent concurrent uv processes from downloading and extracting the same remote wheel more than once ([#&#8203;21379](https://github.com/astral-sh/uv/pull/21379)) - Speed up dependency graph construction from large lockfiles by indexing packages during traversal ([#&#8203;21373](https://github.com/astral-sh/uv/pull/21373)) - Extend indexed lockfile traversal to exports, dependency trees, audits, and freshness checks ([#&#8203;21377](https://github.com/astral-sh/uv/pull/21377)) - Speed up warm resolutions by reducing repeated marker interner work ([#&#8203;21300](https://github.com/astral-sh/uv/pull/21300)) ##### Bug fixes - Do not trust hashes from direct URLs discovered only in wheel metadata when installing with `--require-hashes` ([#&#8203;21348](https://github.com/astral-sh/uv/pull/21348)) - Use a compatible Azure Storage API version for anonymous and authenticated requests, allowing credential retries when public access is disabled ([#&#8203;21366](https://github.com/astral-sh/uv/pull/21366)) - Redact Azure shared access signature (`sig`) query parameters from displayed URLs ([#&#8203;21360](https://github.com/astral-sh/uv/pull/21360)) - Treat projects below one-level workspace member globs as standalone instead of aborting workspace discovery ([#&#8203;21341](https://github.com/astral-sh/uv/pull/21341)) ##### Other changes - Update `astral-tokio-tar` to 0.7.0 and use effective sizes when tracking extracted hard links ([#&#8203;21346](https://github.com/astral-sh/uv/pull/21346)) ### [`v0.12.7`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0127) [Compare Source](https://github.com/astral-sh/uv/compare/0.12.6...0.12.7) Released on 2026-08-27. ##### Python - Replace managed Python installations when upgrading to a newer build of the same version ([#&#8203;21323](https://github.com/astral-sh/uv/pull/21323)) ##### Enhancements - Support Linux `s390x`, `ppc64le`, and `loongarch64` targets for cross-platform dependency resolution ([#&#8203;21313](https://github.com/astral-sh/uv/pull/21313)) - Retry downloads with configured credentials when Azure Storage denies anonymous access to an endpoint configured via `UV_AZURE_ENDPOINT_URL` ([#&#8203;21318](https://github.com/astral-sh/uv/pull/21318)) ##### Preview features - Use content-based directory hashes to deduplicate extracted wheels in the cache with the `content-addressed-cache` preview feature ([#&#8203;19693](https://github.com/astral-sh/uv/pull/19693)) ##### Bug fixes - Reject source archives with hash mismatches before persisting their extracted contents to the cache ([#&#8203;21248](https://github.com/astral-sh/uv/pull/21248)) ##### Other changes - remove pyx specific features ([#&#8203;21182](https://github.com/astral-sh/uv/pull/21182), [#&#8203;21183](https://github.com/astral-sh/uv/pull/21183), [#&#8203;21184](https://github.com/astral-sh/uv/pull/21184), [#&#8203;21185](https://github.com/astral-sh/uv/pull/21185), [#&#8203;21186](https://github.com/astral-sh/uv/pull/21186)) ### [`v0.12.6`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0126) [Compare Source](https://github.com/astral-sh/uv/compare/0.12.5...0.12.6) Released on 2026-08-25. ##### Python - Update CPython to use OpenSSL 3.5.8 and libffi 3.4.8 [#&#8203;21295](https://github.com/astral-sh/uv/pull/21295)) ##### Enhancements - Report cache-cleaning space savings from filesystem block allocation and avoid double-counting hard links ([#&#8203;21261](https://github.com/astral-sh/uv/pull/21261)) - Limit warnings about unbounded `uv_build` requirements to source-distribution builds ([#&#8203;21078](https://github.com/astral-sh/uv/pull/21078)) - Display byte counts below 1 KiB without a fractional part ([#&#8203;21237](https://github.com/astral-sh/uv/pull/21237)) ##### Preview features - Add `uv workspace metadata --sync --exact` to remove packages outside the selected resolution ([#&#8203;21117](https://github.com/astral-sh/uv/pull/21117)) - Add the `artifact-hash-filtering` preview feature to make `uv pip compile --generate-hashes` honor `--only-binary` and `--no-binary` ([#&#8203;21235](https://github.com/astral-sh/uv/pull/21235)) - Respect package-specific `exclude-newer` cutoffs when `uv check` selects its `ty` executable ([#&#8203;21227](https://github.com/astral-sh/uv/pull/21227)) - Preserve virtual-environment hints from `tar-codec` source-distribution errors when the base interpreter is outside a `bin` directory ([#&#8203;21146](https://github.com/astral-sh/uv/pull/21146)) ##### Performance - Enable profile-guided optimization for Linux x86-64 release binaries ([#&#8203;21001](https://github.com/astral-sh/uv/pull/21001)) - Enable profile-guided optimization for Windows x86-64 release binaries ([#&#8203;21003](https://github.com/astral-sh/uv/pull/21003)) - Enable profile-guided optimization for macOS ARM64 release binaries ([#&#8203;21002](https://github.com/astral-sh/uv/pull/21002)) - Enable profile-guided optimization for Linux ARM64 release binaries ([#&#8203;21004](https://github.com/astral-sh/uv/pull/21004)) - Speed up syncing projects with many activated conflict items by reusing their encoded representation ([#&#8203;21148](https://github.com/astral-sh/uv/pull/21148)) ##### Bug fixes - Allow explicit `uv build` and non-editable first-party workspace packages when `no-build` is enabled ([#&#8203;21294](https://github.com/astral-sh/uv/pull/21294)) - Reuse configured index credentials during `uv tool upgrade` when the tool receipt references the same index ([#&#8203;21275](https://github.com/astral-sh/uv/pull/21275)) - Ensure full 40-character Git commit pins resolve to the requested object instead of a SHA-named branch ([#&#8203;21224](https://github.com/astral-sh/uv/pull/21224)) - Prevent TLS segfaults in riscv64 musl release binaries ([#&#8203;21158](https://github.com/astral-sh/uv/pull/21158)) - Preserve dependencies selected by recursive extras when markers mix production and extra conditions ([#&#8203;21181](https://github.com/astral-sh/uv/pull/21181)) - Preserve version constraints from transitively referenced recursive extras ([#&#8203;21209](https://github.com/astral-sh/uv/pull/21209)) - Resolve repository-relative Git archive dependencies inside the checkout during the initial `uv sync` ([#&#8203;21264](https://github.com/astral-sh/uv/pull/21264)) - Return an error instead of panicking when a bearer token cannot be encoded as an HTTP header ([#&#8203;21282](https://github.com/astral-sh/uv/pull/21282)) - Do not misclassify package URLs ending in `.py` as local script paths ([#&#8203;21144](https://github.com/astral-sh/uv/pull/21144)) - Use directory creation times consistently across libc implementations for directory `cache-keys` entries ([#&#8203;21137](https://github.com/astral-sh/uv/pull/21137)) - Promote human-readable sizes to the next unit at rounding boundaries ([#&#8203;21136](https://github.com/astral-sh/uv/pull/21136)) ##### Other changes - Add Python 3.15 release-candidate Docker images ([#&#8203;21293](https://github.com/astral-sh/uv/pull/21293)) - Raise the minimum supported Rust version to 1.96 and update the repository toolchain to Rust 1.98 ([#&#8203;21258](https://github.com/astral-sh/uv/pull/21258)) ### [`v0.12.5`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0125) [Compare Source](https://github.com/astral-sh/uv/compare/0.12.4...0.12.5) Released on 2026-08-14. ##### Python - Add CPython 3.10.21, 3.11.16, and 3.12.14 ([#&#8203;21138](https://github.com/astral-sh/uv/pull/21138)) - Prefer newer versions and standard variants when selecting between equally prioritized Python interpreters ([#&#8203;21134](https://github.com/astral-sh/uv/pull/21134)) ##### Enhancements - Simplify errors and hints for invalid editable requirements, and redact credentials in requirement URLs ([#&#8203;21130](https://github.com/astral-sh/uv/pull/21130)) ##### Preview features - Allow `--index` and `--default-index` to select configured package indexes by name with the `index-by-name` preview feature ([#&#8203;17455](https://github.com/astral-sh/uv/pull/17455)) - Include distribution artifact URLs and hashes in CycloneDX SBOM exports by default ([#&#8203;21131](https://github.com/astral-sh/uv/pull/21131)) - Fall back to logical file sizes when using `cache-physical-space` on filesystems that do not support physical-space accounting ([#&#8203;21133](https://github.com/astral-sh/uv/pull/21133)) ##### Bug fixes - Resolve relative package index paths in PEP 723 scripts against the script directory ([#&#8203;21097](https://github.com/astral-sh/uv/pull/21097)) ### [`v0.12.4`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0124) [Compare Source](https://github.com/astral-sh/uv/compare/0.12.3...0.12.4) Released on 2026-08-13. ##### Enhancements - Prefer post-quantum key exchange and enable opt-in TLS diagnostics ([#&#8203;21054](https://github.com/astral-sh/uv/pull/21054)) - Accept whitespace before versions in noncompliant wildcard comparisons such as `Requires-Python: >= 3.5.*` ([#&#8203;21012](https://github.com/astral-sh/uv/pull/21012)) - Report a specific error when a PEP 723 closing tag contains trailing whitespace or other content ([#&#8203;20944](https://github.com/astral-sh/uv/pull/20944)) - Omit source-span carets from diagnostics for empty PEP 508 requirements ([#&#8203;21094](https://github.com/astral-sh/uv/pull/21094)) ##### Preview features - Add `uv check --no-install-project` and respect `UV_NO_INSTALL_PROJECT` to install dependencies without building or installing the project ([#&#8203;21085](https://github.com/astral-sh/uv/pull/21085)) - Make the ty subprocess invoked by `uv check` honor uv's color and progress settings, including quiet mode ([#&#8203;21086](https://github.com/astral-sh/uv/pull/21086)) ##### Performance - Speed up resolutions with long runs of unavailable package versions by coalescing gaps in the resolver's version ranges ([#&#8203;20804](https://github.com/astral-sh/uv/pull/20804)) - Speed up Simple API parsing by deserializing PyPI and Pyx file metadata directly ([#&#8203;21041](https://github.com/astral-sh/uv/pull/21041)) ##### Bug fixes - Use windowed `pythonw.exe` launchers for virtual environments created from managed Python minor-version links ([#&#8203;19235](https://github.com/astral-sh/uv/pull/19235)) - Allow `uv lock` to proceed when `.venv` is an unusable project environment ([#&#8203;21068](https://github.com/astral-sh/uv/pull/21068)) - Respect `fork-strategy` when ordering forks created from `environments` or existing lockfile `resolution-markers` ([#&#8203;21000](https://github.com/astral-sh/uv/pull/21000)) - Preserve consecutive wildcard Python minor-version exclusions such as `!=3.11.*, !=3.12.*` in `uv.lock` ([#&#8203;21045](https://github.com/astral-sh/uv/pull/21045)) - Preserve inline comments on the final item in dependency arrays when `uv add` updates it ([#&#8203;21008](https://github.com/astral-sh/uv/pull/21008)) - Recover from stale base-interpreter cache metadata when an existing virtual environment exposes a version mismatch ([#&#8203;21073](https://github.com/astral-sh/uv/pull/21073)) - Prevent interpreter cache reuse across different `PYTHONEXECUTABLE` and `__PYVENV_LAUNCHER__` overrides ([#&#8203;21075](https://github.com/astral-sh/uv/pull/21075)) - Show standard styling, usage guidance, and line termination for invalid `uv version --bump` values ([#&#8203;21076](https://github.com/astral-sh/uv/pull/21076)) ### [`v0.12.3`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0123) [Compare Source](https://github.com/astral-sh/uv/compare/0.12.2...0.12.3) Released on 2026-08-07. ##### Python - Add CPython 3.13.15 ([#&#8203;20997](https://github.com/astral-sh/uv/pull/20997)) ##### Preview features - Add `--output-format` to select automatic, human-readable, or raw-byte output for `uv cache size` ([#&#8203;20992](https://github.com/astral-sh/uv/pull/20992)) - Preserve JSON output from `uv workspace metadata --quiet` while suppressing diagnostics ([#&#8203;20991](https://github.com/astral-sh/uv/pull/20991)) - Reduce memory usage for large workspaces by streaming `uv workspace metadata` JSON output ([#&#8203;20990](https://github.com/astral-sh/uv/pull/20990)) ##### Performance - Reduce Linux startup latency by initializing the workspace cache before spawning another thread ([#&#8203;20989](https://github.com/astral-sh/uv/pull/20989)) - Reuse compiled workspace exclusion patterns during workspace discovery ([#&#8203;20988](https://github.com/astral-sh/uv/pull/20988)) - Speed up conflict-heavy resolutions by avoiding materialized range complements ([#&#8203;20982](https://github.com/astral-sh/uv/pull/20982)) - Avoid slow procfs reads during Python interpreter discovery on Linux ([#&#8203;20987](https://github.com/astral-sh/uv/pull/20987)) ##### Documentation - Add PEP 740 attestations to the GitHub Actions publishing example ([#&#8203;20986](https://github.com/astral-sh/uv/pull/20986)) - Restrict the GitHub Actions publishing example to Python version tags ([#&#8203;20973](https://github.com/astral-sh/uv/pull/20973)) - Correct `--python-pin` to `--pin-python` in the `uv init --bare` example ([#&#8203;20876](https://github.com/astral-sh/uv/pull/20876)) ### [`v0.12.2`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0122) [Compare Source](https://github.com/astral-sh/uv/compare/0.12.1...0.12.2) Released on 2026-08-05. ##### Python - Add CPython 3.15.0rc1 ([#&#8203;20948](https://github.com/astral-sh/uv/pull/20948)) - Add CPython 3.14.7 ([#&#8203;20971](https://github.com/astral-sh/uv/pull/20971)) ##### Enhancements - Ensure diagnostic hints end with a newline to prevent malformed terminal output ([#&#8203;20959](https://github.com/astral-sh/uv/pull/20959)) ##### Preview features - Audit one or all installed tools with `uv tool audit` ([#&#8203;20921](https://github.com/astral-sh/uv/pull/20921)) - Report physically reclaimed disk space during cache cleanup with the `cache-physical-space` preview feature ([#&#8203;20925](https://github.com/astral-sh/uv/pull/20925)) ##### Configuration - Add `UV_RUN_RLIMIT_NOFILE` to set the open-file limit for commands launched by `uv run` ([#&#8203;20926](https://github.com/astral-sh/uv/pull/20926)) ##### Performance - Speed up `uv.lock` parsing for wheel entries ([#&#8203;20881](https://github.com/astral-sh/uv/pull/20881)) - Speed up `uv.lock` parsing for source distribution entries ([#&#8203;20882](https://github.com/astral-sh/uv/pull/20882)) - Speed up filename extraction from distribution URLs ([#&#8203;20879](https://github.com/astral-sh/uv/pull/20879)) - Reduce filesystem metadata lookups during bytecode compilation ([#&#8203;20928](https://github.com/astral-sh/uv/pull/20928)) - Reuse file metadata when building source distributions ([#&#8203;20927](https://github.com/astral-sh/uv/pull/20927)) ##### Bug fixes - Preserve compatibility with older uv versions when recording artifact sizes in cached wheels and source distributions ([#&#8203;20963](https://github.com/astral-sh/uv/pull/20963)) - Avoid including workspace-root default dependency groups when syncing or exporting a selected workspace member unless explicitly requested ([#&#8203;20930](https://github.com/astral-sh/uv/pull/20930)) ##### Documentation - Separate build and publish jobs in the GitHub Actions publishing guide ([#&#8203;20946](https://github.com/astral-sh/uv/pull/20946)) - Ensure the GitHub Actions publishing example waits for the build job to finish ([#&#8203;20957](https://github.com/astral-sh/uv/pull/20957)) - Correct typos in the Docker integration guide ([#&#8203;20970](https://github.com/astral-sh/uv/pull/20970)) ### [`v0.12.1`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#01215) [Compare Source](https://github.com/astral-sh/uv/compare/0.12.0...0.12.1) Released on 2026-09-15. This release fixes a regression in 0.12.14 that lead to rejecting valid installation commands such as using `uv pip install --system` in `python:*` docker images or when using `uv pip install --target .`. ([#&#8203;21699](https://github.com/astral-sh/uv/pull/21699)) ##### Performance - Speed up cold-cache resolution and HTTP cache revalidation by batching cache writes ([#&#8203;21675](https://github.com/astral-sh/uv/pull/21675)) ##### Bug fixes - Revert "Reject symlinked wheel installation destinations" ([#&#8203;21699](https://github.com/astral-sh/uv/pull/21699)) ### [`v0.12.0`](https://github.com/astral-sh/uv/blob/HEAD/CHANGELOG.md#0120) [Compare Source](https://github.com/astral-sh/uv/compare/0.11.33...0.12.0) Released on 2026-07-28. Since we released uv [0.11.0](https://github.com/astral-sh/uv/releases/tag/0.11.0) in March, we've accumulated changes that improve correctness, safety, and compatibility with specifications, but could break some workflows. This release contains those changes; many have been marked as breaking out of an abundance of caution. **We expect most users to be able to upgrade without making changes.** There are no breaking changes to the configuration of the [uv build backend](https://docs.astral.sh/uv/concepts/build-backend/). If your `[build-system]` table includes an upper bound on `uv_build`, update it to allow `uv_build` 0.12, e.g., `uv_build>=0.11.32,<0.13`. ##### Breaking changes - **Define build systems by default with `uv init`** ([#&#8203;19197](https://github.com/astral-sh/uv/pull/19197)) Projects created with `uv init` now declare a build system and are packaged by default. This was the default project layout all the way back in [v0.3](https://github.com/astral-sh/uv/releases/tag/0.3.0), but we found that the use of the `hatchling` build system was confusing to newcomers and consequently dropped use of a build system by default in [v0.4](https://github.com/astral-sh/uv/releases/tag/0.4.0). Since then, we've created our own build system (`uv_build`) with tight integration with uv and are excited to restore the default to a best-practice project layout. Previously, `uv init example` created an unpackaged layout containing `main.py` and a `pyproject.toml` without a build system. The project could declare dependencies but was not itself installed into its virtual environment. Now, `uv init example` defines a `[build-system]` using `uv_build`, places application source code in `src/example`, and includes a `[project.scripts]` entry named `example`. Defining a build system allows the project to be imported from tests or other code, installed as a dependency, and run as a command: ```console $ uv init example $ cd example $ uv run example Hello from example! ``` Existing projects are unaffected. Use [`uv init --no-package example`](https://docs.astral.sh/uv/concepts/projects/init/#creating-a-project-without-a-build-system) to create the previous unpackaged layout without a build system. See the [project creation documentation](https://docs.astral.sh/uv/concepts/projects/init/#applications) for more details. This stabilizes the `packaged-init` preview feature. - **Reject unsupported source distribution and wheel archive formats** ([#&#8203;18927](https://github.com/astral-sh/uv/pull/18927)) [PEP 625](https://peps.python.org/pep-0625/) requires [source distributions](https://docs.astral.sh/uv/concepts/resolution/#source-distribution) to use `.tar.gz` archives. Previously, uv also accepted legacy formats such as `.tar.bz2` and `.tar.xz`. Those formats are now rejected, including when referenced by an existing lockfile. Legacy `.zip` source distributions remain supported for backwards compatibility. Wheels and other ZIP archives can no longer contain entries compressed with bzip2, LZMA, or XZ. Entries must use the stored, DEFLATE, or zstd compression methods. Removing support for uncommon compression methods reduces uv's compression dependencies and the attack surface exposed when processing untrusted packages. You cannot opt out of this behavior. If you depend on a legacy source distribution that uses an unsupported format, we recommend rebuilding it as a `.tar.gz` archive and regenerating any lockfile containing references to the legacy archive. - **Reject wheel files that could replace the Python interpreter** ([#&#8203;20748](https://github.com/astral-sh/uv/pull/20748), [#&#8203;20749](https://github.com/astral-sh/uv/pull/20749)) uv already rejected wheel entry points named `python`, but case variants such as `Python` were still accepted. On case-insensitive filesystems, including common macOS and Windows setups, these entry points could overwrite the virtual environment's interpreter. Wheels could also place interpreter files in their `.data/scripts` directory or in paths such as `.data/data/bin/python`, bypassing the entry-point check and replacing the interpreter during installation. uv now rejects case-insensitive variants of reserved interpreter names and wheel data files that would be installed over an interpreter. This includes names such as `Python`, `python.py`, and `Python.exe`, along with other reserved interpreter names and their versioned variants. You cannot opt out of these checks. Rename conflicting entry points or wheel data files and rebuild the affected wheel. - **Prefer stable releases before falling back to pre-releases** ([#&#8203;19993](https://github.com/astral-sh/uv/pull/19993)) A dependency can introduce a [pre-release requirement](https://docs.astral.sh/uv/concepts/resolution/#pre-release-handling) after resolution starts. uv previously required each package's pre-release eligibility to be known before resolution began: the default `if-necessary-or-explicit` mode allowed them for direct requirements that explicitly requested a pre-release, or for packages that only published pre-releases. This meant that a pre-release requirement discovered in a dependency's metadata, e.g., `example>=2.0.0b1`, would fail to resolve even when a compatible pre-release existed. To resolve it, you had to add that dependency as a direct requirement or allow pre-releases across your entire dependency graph. The default mode is now `if-necessary`. uv tries stable candidates first and falls back to pre-releases when no stable candidate satisfies the active constraints. Like pip, uv now supports [pre-release requirements discovered transitively](https://docs.astral.sh/uv/pip/compatibility/#pre-release-compatibility), but can select different versions than previous uv releases when both stable and pre-release candidates are available. You can opt out of automatic pre-release selection with `--prerelease disallow`. Alternatively, `--prerelease allow` considers pre-releases without first preferring stable releases, and `--prerelease explicit` only allows them for direct requirements that mention a pre-release. The old `if-necessary-or-explicit` mode distinguished between explicitly requested pre-releases and packages with no stable releases. That distinction is unnecessary now that `if-necessary` handles both cases, including transitive requirements. The old name remains available as an alias but is deprecated and will be removed in a future release. - **Respect `--require-hashes` directives in `requirements.txt`** ([#&#8203;19336](https://github.com/astral-sh/uv/pull/19336)) Previously, `uv pip install` and `uv pip sync` warned about `--require-hashes` inside a `requirements.txt` file but still installed dependencies without checking their hashes. Now, the directive enables hash-checking mode, just as if `--require-hashes` had been passed on the command line. For example, this requirements file is no longer accepted because the requirement is neither pinned nor hashed: ```text --require-hashes anyio ``` You cannot opt out while the directive is present. Pin every requirement with `==` and provide its hash, or remove `--require-hashes` if hash checking is not intended. - **Reject MD5-only hashes in hash-checking mode** ([#&#8203;20758](https://github.com/astral-sh/uv/pull/20758)) Previously, `uv pip install --require-hashes` and `uv pip sync --require-hashes` accepted requirements whose only available digest used MD5. MD5 is not collision-resistant, so relying on it undermined installations that require hash verification and differed from pip's behavior. Hash-checking mode now requires at least one secure digest for every requirement. For example, the following requirement is rejected unless a secure hash, such as SHA-256, is also supplied: ```text anyio==4.0.0 --hash=md5:420d85e19168705cdf0223621b18831a ``` A secure hash can be supplied directly on the requirement or in a matching constraints file. Ordinary hash verification without `--require-hashes` continues to support MD5. You cannot opt out while hash checking is required. Regenerate affected hashes with SHA-256 or another supported secure hash. - **Reject invalid `pylock.toml` files and artifacts** ([#&#8203;20402](https://github.com/astral-sh/uv/pull/20402), [#&#8203;20440](https://github.com/astral-sh/uv/pull/20440), [#&#8203;20443](https://github.com/astral-sh/uv/pull/20443)) uv now validates additional requirements from the [`pylock.toml` specification](https://packaging.python.org/en/latest/specifications/pylock-toml/): - The `packages` array must be present. Previously, uv interpreted a missing array as an empty lockfile, so `uv pip sync` could uninstall an environment instead of rejecting malformed input. An explicitly empty `packages = []` array remains valid. - Lockfile filenames must be `pylock.toml` or a single-name variant such as `pylock.dev.toml`. Names such as `pylock..toml` and `pylock.foo.bar.toml` are rejected. - If a wheel, source distribution, or other artifact declares a `size`, the downloaded or cached artifact must match. Previously, an incorrect size was accepted when the hash was correct. Sizes reported by package indexes remain advisory. You cannot opt out of these checks. Regenerate malformed lockfiles, rename invalid filenames, and either correct or remove an incorrect optional `size` value. - **Honor explicit certificate overrides even when no certificates can be loaded** ([#&#8203;20741](https://github.com/astral-sh/uv/pull/20741), [#&#8203;20767](https://github.com/astral-sh/uv/pull/20767)) Previously, uv ignored [`SSL_CERT_FILE` or `SSL_CERT_DIR`](https://docs.astral.sh/uv/concepts/authentication/certificates/#custom-certificates) values that pointed to missing or inaccessible paths, empty files or directories, or sources without valid certificates. Instead, it fell back to its default trust roots, potentially allowing HTTPS connections that the configured override was intended to reject. Now, any non-empty `SSL_CERT_FILE` or `SSL_CERT_DIR` value replaces uv's default certificate roots, even when no valid certificates can be loaded. In that case, HTTPS requests fail because no certificates are trusted. This applies to package downloads and remote scripts, including GitHub Gists. Fix or unset the certificate override. Unsetting it restores the default trust store; empty environment-variable values continue to be ignored. - **Support pip-compatible `--cert` handling in `uv pip`** ([#&#8203;20418](https://github.com/astral-sh/uv/pull/20418)) The `uv pip` interface now accepts [`--cert <path>`](https://docs.astral.sh/uv/concepts/authentication/certificates/#custom-certificates), e.g.: ```console $ uv pip install --cert ./company-ca.pem example ``` As in pip, the provided PEM bundle replaces all other certificate sources for that invocation, including system certificates and `SSL_CERT_FILE` or `SSL_CERT_DIR`. This change has no effect unless you pass `--cert`. Include the necessary certificate authorities in the bundle. `--cert` is only supported by `uv pip` commands; other uv commands continue to use their existing certificate configuration. - **Discover projects relative to the script passed to `uv run`** ([#&#8203;20225](https://github.com/astral-sh/uv/pull/20225)) Previously, `uv run project/script.py` discovered its project from the current directory, even when the script belonged to another project. uv now starts project and workspace discovery from the script's directory instead. For example, running `uv run other-project/script.py` now uses `other-project` and its dependencies. This fixes scripts that previously failed because their own dependencies were not installed, but can select a different environment than before. You can opt out of script-relative discovery by selecting a project explicitly, e.g., `uv run --project . other-project/script.py`. This stabilizes the `target-workspace-discovery` preview feature. - **Require `--force` before clearing a directory that is not a virtual environment** ([#&#8203;20225](https://github.com/astral-sh/uv/pull/20225)) `uv venv --clear` previously removed any existing target directory, even if it was not a virtual environment. uv emitted a warning but still deleted the directory and its contents. Now, uv refuses to clear directories that do not contain a virtual environment. You can opt out of this safety check by explicitly passing `--force`, e.g., `uv venv --clear --force ./not-a-virtualenv`. This stabilizes the `venv-safe-clear` preview feature. - **Reject `--project` when initializing a project** ([#&#8203;20225](https://github.com/astral-sh/uv/pull/20225)) `--project` selects an existing project, so it is not meaningful when initializing a new one. Previously, `uv init --project example` warned and initialized `example` anyway; if a positional path was also provided, `--project` was ignored. This usage is now an error. Use `uv init example` to initialize a project at the requested path, or `uv init --directory example` to change the working directory first. This stabilizes the `init-project-flag` preview feature. - **Reject missing or invalid `--project` paths** ([#&#8203;20225](https://github.com/astral-sh/uv/pull/20225)) uv previously warned when `--project` referred to a missing directory or a file other than `pyproject.toml`, but then attempted to continue. This could produce confusing errors later or run against an unintended project. Now, `uv run --project missing python` fails immediately instead of continuing. You cannot opt out of this behavior. Create the directory first or select an existing project. Passing `--project path/to/pyproject.toml` remains supported and selects the file's parent directory. This stabilizes the `project-directory-must-exist` preview feature. - **Skip distributions with non-normalized filenames when publishing** ([#&#8203;20225](https://github.com/astral-sh/uv/pull/20225)) Distribution filenames must use [normalized package names](https://packaging.python.org/en/latest/specifications/name-normalization/) and versions. For example, a wheel for version `1.01.0` should be named `example-1.1.0-py3-none-any.whl`, not `example-1.01.0-py3-none-any.whl`. Previously, `uv publish` warned about non-normalized filenames but still attempted to upload them. It now skips the affected wheels and source distributions instead. You cannot opt out of this behavior. Rebuild distributions with normalized filenames before publishing. This stabilizes the `publish-require-normalized` preview feature. - **Classify Conda environments named `base` and `root` by their paths** ([#&#8203;20225](https://github.com/astral-sh/uv/pull/20225)) Conda environments named `base` or `root` were previously assumed to be the base Conda environment, even when they were ordinary child environments. uv now recognizes child Conda environments named `base` or `root` based on their paths, as it already does for other names. You can opt out of automatic interpreter selection by requesting an interpreter explicitly with `--python /path/to/python`. This stabilizes the `special-conda-env-names` preview feature. - **Reject broken `.venv` symlinks during environment discovery** ([#&#8203;20433](https://github.com/astral-sh/uv/pull/20433)) Previously, uv could ignore a broken `.venv` symlink and continue searching parent directories for another virtual environment. As a result, commands such as `uv pip install` could unexpectedly modify an unrelated ancestor environment. uv now stops at a broken `.venv` symlink and reports its exact path. Errors encountered while reading virtual environment metadata, including permission failures, are also reported immediately instead of being ignored. You cannot opt out of this behavior. Repair or remove the broken `.venv` symlink and correct any permissions that prevent uv from inspecting the environment. - **Reinstall matching installed Python patch versions instead of upgrading implicitly** ([#&#8203;20659](https://github.com/astral-sh/uv/pull/20659)) Before [Python upgrades](https://docs.astral.sh/uv/guides/install-python/#upgrading-python-versions) were supported, `uv python install 3.12 --reinstall` doubled as a way to install the latest Python 3.12 patch release. Now that `--upgrade` is available, `--reinstall` reinstalls the matching patch releases that are already present. For example, if Python 3.12.6 and 3.12.7 are installed, `uv python install 3.12 --reinstall` reinstalls both versions instead of installing the latest available 3.12 release. You can recover the previous upgrade behavior with `uv python install 3.12 --upgrade`. Combine `--upgrade --reinstall` to reinstall only the latest patch. - **Require `--upgrade-group` to name an existing dependency group** ([#&#8203;18957](https://github.com/astral-sh/uv/pull/18957)) Previously, `uv lock --upgrade-group docs` silently succeeded even if no `docs` [dependency group](https://docs.astral.sh/uv/concepts/projects/dependencies/#dependency-groups) existed. uv now validates the requested group against the project, its workspace members, and workspace-level dependency groups. You cannot opt out of this behavior. Correct the group name or add it to `[dependency-groups]`. Legacy `tool.uv.dev-dependencies` still satisfies `--upgrade-group dev`. - **Resolve relative indexes and find-links against `--directory`** ([#&#8203;20740](https://github.com/astral-sh/uv/pull/20740)) The `--directory` option changes the directory in which uv operates. Previously, relative index and find-links paths supplied on the command line were still resolved against the original working directory. uv now resolves `--index`, `--default-index`, `--index-url`, `--extra-index-url`, and `--find-links` relative to the directory selected by `--directory`. For example: ```console $ uv add --directory project --index ./packages example ``` This now uses `project/packages` instead of `./packages` in the original working directory. Absolute paths and indexes loaded from configuration files are unaffected. To preserve the previous target, pass an absolute path or adjust the relative path, e.g., `--index ../packages`. - **Preserve absolute paths provided to `uv add`** ([#&#8203;18402](https://github.com/astral-sh/uv/pull/18402)) `uv add` previously converted every local dependency into a project-relative path, even when the original request used an absolute path or a literal `file://` URL. It now preserves the form of the request in `pyproject.toml` and `uv.lock`: ```console $ uv add ../library # remains relative $ uv add /projects/library # remains absolute ``` Absolute paths make a project less portable. Use a relative path to avoid recording an absolute path. URLs containing expanded variables retain their existing relative-path behavior. - **Remove older PyPy distributions that are only available as bzip2 archives** ([#&#8203;20423](https://github.com/astral-sh/uv/pull/20423)) Older PyPy patch releases that are only distributed as `.tar.bz2` archives are no longer available through `uv python install`. These releases require unsupported bzip2 archives. The latest PyPy release for each supported Python minor version is available as a gzip-compressed archive and remains supported. For example, `uv python list 3.10 --all-versions` still includes the latest PyPy 3.10 release, but older bzip2-only patch releases are omitted. You cannot opt out of this behavior. Request a newer PyPy patch release instead. - **Omit excluded-package comments when annotations are disabled** ([#&#8203;20085](https://github.com/astral-sh/uv/pull/20085)) `uv pip compile --no-annotate` suppresses comments describing the generated requirements file. Previously, a footer listing packages excluded with `--unsafe-package` was still included, even though annotations were disabled. That footer is now omitted. You can recover the footer by removing `--no-annotate`. ##### Stabilizations - **TOML 1.0-compatible source distributions** ([#&#8203;20225](https://github.com/astral-sh/uv/pull/20225)) `uv_build` now writes a TOML 1.0-compatible `pyproject.toml` when building source distributions, allowing older Python build frontends to consume projects that use newer TOML syntax. The original project file remains available in the archive as `pyproject.toml.orig`. This stabilizes the `toml-backwards-compatibility` preview feature. - **Automatic open-file limit adjustment on Unix** ([#&#8203;20225](https://github.com/astral-sh/uv/pull/20225)) On Linux and macOS, uv now attempts to raise the soft open-file limit at startup toward the hard limit, capped at 1,048,576 descriptors. The new limit also applies to subprocesses and reduces failures caused by running out of file descriptors. If the limit cannot be raised, uv continues running with the existing limit. This stabilizes the `adjust-ulimit` preview feature. ##### Preview features - Allow `uv upgrade` to target multiple packages, upgrade all production dependencies, and exclude selected dependencies ([#&#8203;20338](https://github.com/astral-sh/uv/pull/20338)) ##### Bug fixes - Include extras activated by dependency groups when evaluating conflicts ([#&#8203;20237](https://github.com/astral-sh/uv/pull/20237)) </details> --- ### Configuration 📅 **Schedule**: (in timezone Europe/Warsaw) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC43NC4wIiwidXBkYXRlZEluVmVyIjoiNDQuNzQuMCIsInRhcmdldEJyYW5jaCI6ImRldiIsImxhYmVscyI6WyJkZXBzLWNvZGUiLCJyZW5vdmF0ZSJdfQ==-->
renovate Bot added the deps-coderenovate labels 2026-09-15 21:56:34 +00:00
renovate Bot added 1 commit 2026-09-15 21:56:35 +00:00
chore(deps): update code dependencies
renovate/stability-days Updates have met minimum release age requirement
5e3b469dd0
renovate Bot scheduled this pull request to auto merge when all checks succeed 2026-09-15 21:56:36 +00:00
renovate Bot merged commit 81ebbdc93e into dev 2026-09-15 21:56:38 +00:00
renovate Bot deleted branch renovate/dev-code-dependencies 2026-09-15 21:56:38 +00:00
Sign in to join this conversation.