github biomejs/biome @biomejs/biome@2.4.9
Biome CLI v2.4.9

7 hours ago

2.4.9

Patch Changes

  • #9315 085d324 Thanks @ematipico! - Added a new nursery CSS rule noDuplicateSelectors, that disallows duplicate selector lists within the same at-rule context.

    For example, the following snippet triggers the rule because the second selector and the first selector are the same:

    /* First selector */
    .x .y .z {
    }
    
    /* Second selector */
    .x {
      .y {
        .z {
        }
      }
    }
  • #9567 b7ab931 Thanks @ematipico! - Fixed #7211: useOptionalChain now detects negated logical OR chains. The following code is now considered invalid:

    !foo || !foo.bar;
  • #8670 607ebf9 Thanks @tt-a1i! - Fixed #8345: useAdjacentOverloadSignatures no longer reports false positives for static and instance methods with the same name. Static methods and instance methods are now treated as separate overload groups.

    class Kek {
      static kek(): number {
        return 0;
      }
      another(): string {
        return "";
      }
      kek(): number {
        return 1;
      } // no longer reported as non-adjacent
    }
  • #9476 97b80a8 Thanks @masterkain! - Fixed #9475: Fixed a panic when Biome analyzed ambient TypeScript modules containing class constructor, getter, or setter signatures that reference local type aliases. Biome now handles these declarations without crashing during semantic analysis.

  • #9553 0cd5298 Thanks @dyc3! - Fixed a bug where enabling the rules of a whole group, would enable rules that belonged to a domain under the same group.

    For example, linter.rules.correctness = "error" no longer enables React- or Qwik-specific correctness rules unless linter.domains.react, linter.domains.qwik, or an explicit rule config also enables them, or their relative dependencies are installed.

  • #9586 4cafb71 Thanks @dyc3! - Fixed #8828: Grit patterns using export { $foo } from $source now match named re-exports in JavaScript and TypeScript files.

  • #9550 d4e3d6e Thanks @dyc3! - Fixed #9548: Biome now parses conditional expressions whose consequent is an arrow function returning a parenthesized object expression.

  • #8696 a7c19cc Thanks @Faizanq! - Fixed #8685 where noUselessLoneBlockStatements would remove empty blocks containing comments. The rule now preserves these blocks since comments may contain important information like TODOs or commented-out code.

  • #9557 6671ac5 Thanks @datalek! - Fixed #9557: Biome's LSP server no longer crashes on startup when used with editors that don't send workspaceFolders during initialization. This affected any LSP client that only sends rootUri, which is valid per the LSP specification.

  • #9455 1710cf1 Thanks @omar-y-abdi! - Fixed #9174: useExpect now correctly rejects asymmetric matchers in Vitest or Jest like expect.stringContaining(), expect.objectContaining(), and utilities like expect.extend() that are not valid assertions. Previously these constructs caused false negatives, allowing tests without real assertions to pass the lint rule.

  • #9584 956e367 Thanks @ematipico! - Fixed a bug where Vue directive attribute values like v-bind:class="{'dynamic': true}" were incorrectly parsed as JavaScript statements instead of expressions. Object literals inside directive values like :class, v-if, and v-html are now correctly parsed as expressions, preventing spurious parse errors.

  • #9474 e168494 Thanks @ematipico! - Added the new nursery rule noUntrustedLicenses. This rule disallows dependencies that ship with invalid licenses or licenses that don't meet the criteria of your project/organisation.

    The rule has the following options:

    • allow: a list of licenses that can be allowed. Useful to bypass possible invalid licenses from downstream dependencies.
    • deny: a list of licenses that should trigger the rule. Useful to deny licenses that don't fit your project/organisation.
      When both deny and allow are provided, deny takes precedence.
    • requireOsiApproved: whether the licenses need to be approved by the Open Source Initiative.
    • requireFsfLibre: whether the licenses need to be approved by the Free Software Foundation.
  • #9544 723798b Thanks @ViniciusDev26! - Added an unsafe fix to useConsistentMethodSignatures that automatically converts between method-style and property-style signatures.

  • #9555 8a3647b Thanks @ematipico! - Fixed #188: the Biome Language Server no longer panics when open files change abruptly, such as during git branch checkouts.

  • #9605 f65c637 Thanks @ematipico! - Fixed #9589. Now Biome correctly parses object expressions inside props and directives. The following code doesn't emit errors anymore:

    <style is:global define:vars={{ bgLight: light }}>
    <Component name={{ first, name }} />
  • #9565 ccb249e Thanks @eyupcanakman! - Fixed #9505: noUselessStringConcat no longer reports tagged template literals as useless string concatenations. Tagged templates invoke a function and can return non-string values, so combining them with + is not equivalent to a single template literal.

  • #9534 4d050df Thanks @Netail! - Added the nursery rule noInlineStyles. The rule disallows the use of inline style attributes in HTML and the style prop in JSX, including React.createElement calls. Inline styles make code harder to maintain and can interfere with Content Security Policy.

  • #9611 cddaa44 Thanks @gaauwe! - Fixed a regression where Biome LSP could misread editor settings sent through workspace/didChangeConfiguration when the payload was wrapped in a top-level biome key. This caused requireConfiguration and related settings to be ignored in some editors.

What's Changed

  • fix(linter): differentiate static/instance methods in useAdjacentOverloadSignatures by @tt-a1i in #8670
  • fix(parse/js): fix a case where valid js was being interpretted as ts by @dyc3 in #9550
  • fix(lsp): gracefully handle panics by @ematipico in #9555
  • fix(linter): don't remove empty blocks containing comments by @Faizanq in #8696
  • fix(config): don't enable rules with domains when categories are enabled by @dyc3 in #9553
  • fix(lint/useExpect): reject asymmetric matchers and utilities as assertions by @omar-y-abdi in #9455
  • chore(deps): update rust crate bpaf to 0.9.24 by @renovate[bot] in #9500
  • refactor(markdown-parser): decompose is_inline_html into predicate-per-construct by @jfmcdowell in #9467
  • refactor(markdown-parser): decompose inline_list_source_len into scan helpers by @jfmcdowell in #9468
  • fix(deps): update @biomejs packages by @renovate[bot] in #9501
  • fix(js-semantic): register ambient signature scopes by @masterkain in #9476
  • fix(useOptionalChain): fix negated expressions by @ematipico in #9567
  • docs: fix CONTRIBUTING.md codeblock by @Netail in #9573
  • chore: fix vulnerabilities in dependencies by @ematipico in #9576
  • fix(lint): skip noUselessStringConcat for tagged templates by @eyupcanakman in #9565
  • chore(bench/html): add real test fixtures to biome_html_analyze benches by @dyc3 in #9578
  • fix(core): correctly parse vue directives as expressions by @ematipico in #9584
  • feat: apply fix to use consistent method signatures by @ViniciusDev26 in #9544
  • chore: add eslint-migrate-options skill by @dyc3 in #9575
  • test: refactor formatter testing infra by @ematipico in #9588
  • feat(analyze): implement noInlineStyles by @Netail in #9534
  • chore(deps): update docker/dockerfile:1 docker digest to 4a43a54 by @renovate[bot] in #9590
  • chore(deps): update rust:1.94.0-bullseye docker digest to 1695019 by @renovate[bot] in #9591
  • chore(deps): update rust:1.94.0-trixie docker digest to f17e723 by @renovate[bot] in #9593
  • fix(deps): update dependency tailwindcss to ^4.2.2 by @renovate[bot] in #9594
  • chore(deps): update dependency eslint to v9.39.4 by @renovate[bot] in #9497
  • chore(deps): update dependency @types/node to v24.12.0 by @renovate[bot] in #9595
  • chore(deps): update dependency dprint to v0.53.0 by @renovate[bot] in #9596
  • chore(deps): update github-actions by @renovate[bot] in #9598
  • chore(deps): update pnpm to v10.32.1 by @renovate[bot] in #9599
  • ci: fix failure by @ematipico in #9603
  • fix(lsp): crash when client does not send workspaceFolders in InitializeParams by @datalek in #9557
  • fix(core): astro embedding detection by @ematipico in #9605
  • chore(deps): update dependency tombi to v0.9.7 by @renovate[bot] in #9597
  • feat(css): add noDuplicateSelectors by @ematipico in #9315
  • chore: convince robots into self identifying by @dyc3 in #9610
  • fix(lsp): handle wrapped settings in didChangeConfiguration by @gaauwe in #9611
  • feat(linter): add rule noUntrustedLicenses by @ematipico in #9474
  • chore: use npmx.dev badge by @ematipico in #9614
  • docs: break down skills, improve existing ones by @ematipico in #9613
  • chore(deps): update rust crate quickcheck to 1.1.0 by @renovate[bot] in #9600
  • perf(html): inline parse functions by @ematipico in #9609
  • fix(grit): fix queries for export { $foo } ... by @dyc3 in #9586
  • ci: release by @github-actions[bot] in #9620

New Contributors

Full Changelog: https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.8...@biomejs/biome@2.4.9

Don't miss a new biome release

NewReleases is sending notifications on new releases.