All versions since 2.2.2
2.2.2
Patch Changes
-
#7266
b270bb5
Thanks @ematipico! - Fixed an issue where Biome got stuck when analyzing some files. This is usually caused by a bug in the inference engine. Now Biome has some guards in place in case the number of types grows too much, and if that happens, a diagnostic is emitted and the inference is halted. -
#7281
6436180
Thanks @ematipico! - Fixed an issue where the functionscanProject
wouldn’t work as expected. -
#7285
1511d0c
Thanks @rriski! - Partially fixed #6782: JSX node kinds are now supported in GritQL AST nodes. -
#7249
dff85c0
Thanks @ematipico! - Fixed #748, where Biome Language Server didn’t show the unsafe fixes when requesting the quick fixes. Now all LSP editors will show also opt-in, unsafe fixes. -
#7266
b270bb5
Thanks @ematipico! - Fixed #7020: Resolved an issue with analysing types of static member expressions involving unions. If the object type was a union that referenced nested unions, it would trigger an infinite loop as it tried to keep expanding nested unions, and the set of types would grow indefinitely. -
#7209
679b70e
Thanks @patrickshipe! - Resolved an overcorrection inuseImportExtensions
when importing explicit index files.Imports that explicitly reference an index file are now preserved and no longer rewritten to nested index paths.
Example
// Beforeimport "./sub/index";import "./sub/index/index.js";// Afterimport "./sub/index";import "./sub/index.js"; -
#7270
953f9c6
Thanks @arendjr! - Fixed #6172: Resolved an issue with inferring types for rest parameters. This issue caused rest-parameter types to be incorrect, and in some cases caused extreme performance regressions in files that contained many methods with rest-parameter definitions. -
#7234
b7aa111
Thanks @JeetuSuthar! - Fixed #7233: The useIndexOf rule now correctly suggests using indexOf() instead of findIndex().The diagnostic message was incorrectly recommending Array#findIndex() over Array#indexOf(), when it should recommend the opposite for simple equality checks.
-
#7283
0b07f45
Thanks @ematipico! - Fixed #7236. Now Biome correctly migrates JSONC configuration files when they are passed using--config-path
. -
#7239
1d643d8
Thanks @minht11! - Fixed an issue where Svelte globals ($state and so on) were not properly recognized inside.svelte.test.ts/js
and.svelte.spec.ts/js
files. -
#7264
62fdbc8
Thanks @ematipico! - Fixed a regression where when using--log-kind-pretty
wasn’t working anymore as expected. -
#7244
660031b
Thanks @JeetuSuthar! - Fixed #7225: ThenoExtraBooleanCast
rule now preserves parentheses when removingBoolean
calls inside negations.// Before!Boolean(b0 && b1);// After!(b0 && b1); // instead of !b0 && b1 -
#7298
46a8e93
Thanks @unvalley! - Fixed #6695:useNamingConvention
now correctly reports TypeScript parameter properties with modifiers.Previously, constructor parameter properties with modifiers like
private
orreadonly
were not checked against naming conventions. These properties are now treated consistently with regular class properties.
2.2.3
Patch Changes
-
#7353
4d2b719
Thanks @JeetuSuthar! - Fixed #7340: The linter now allows thenavigation
property for view-transition in CSS.Previously, the linter incorrectly flagged
navigation: auto
as an unknown property. This fix addsnavigation
to the list of known CSS properties, following the CSS View Transitions spec. -
#7275
560de1b
Thanks @arendjr! - Fixed #7268: Files that are explicitly passed as CLI arguments are now correctly ignored if they reside in an ignored folder. -
#7358
963a246
Thanks @ematipico! - Fixed #7085, now the rulenoDescendingSpecificity
correctly calculates the specificity of selectors when they are included inside a media query. -
#7387
923674d
Thanks @qraqras! - Fixed #7381, now theuseOptionalChain
rule recognizes optional chaining using Yoda expressions (e.g.,undefined !== foo && foo.bar
). -
#7316
f9636d5
Thanks @Conaclos! - Fixed #7289. The ruleuseImportType
now inlinesimport type
intoimport { type }
when thestyle
option is set toinlineType
.Example:
import type { T } from "mod";// becomesimport { type T } from "mod"; -
#7350
bb4d407
Thanks @siketyan! - Fixed #7261: two characters・
(KATAKANA MIDDLE DOT, U+30FB) and・
(HALFWIDTH KATAKANA MIDDLE DOT, U+FF65) are no longer considered as valid characters in identifiers. Property keys containing these character(s) are now preserved as string literals. -
#7377
811f47b
Thanks @ematipico! - Fixed a bug where the Biome Language Server didn’t correctly compute the diagnostics of a monorepo setting, caused by an incorrect handling of the project status. -
#7245
fad34b9
Thanks @kedevked! - Added the new lint ruleuseConsistentArrowReturn
.This rule enforces a consistent return style for arrow functions.
Invalid
const f = () => {return 1;};This rule is a port of ESLint’s arrow-body-style rule.
-
#7370
e8032dd
Thanks @fireairforce! - Support dynamicimport defer
andimport source
. The syntax looks like:import.source("foo");import.source("x", { with: { attr: "val" } });import.defer("foo");import.defer("x", { with: { attr: "val" } }); -
#7369
b1f8cbd
Thanks @siketyan! - Range suppressions are now supported for Grit plugins.For JavaScript, you can suppress a plugin as follows:
// biome-ignore-start lint/plugin/preferObjectSpread: reasonObject.assign({ foo: "bar" }, baz);// biome-ignore-end lint/plugin/preferObjectSpread: reasonFor CSS, you can suppress a plugin as follows:
body {/* biome-ignore-start lint/plugin/useLowercaseColors: reason */color: #fff;/* biome-ignore-end lint/plugin/useLowercaseColors: reason */} -
#7384
099507e
Thanks @ematipico! - Reduced the severity of certain diagnostics emitted when Biome deserializes the configuration files. Now these diagnostics are emitted asInformation
severity, which means that they won’t interfere when running commands with--error-on-warnings
-
#7302
2af2380
Thanks @unvalley! - Fixed #7301:useReadonlyClassProperties
now correctly skips JavaScript files. -
#7288
94d85f8
Thanks @ThiefMaster! - Fixed #7286. Files are now formatted with JSX behavior whenjavascript.parser.jsxEverywhere
is explicitly set.Previously, this flag was only used for parsing, but not for formatting, which resulted in incorrect formatting of conditional expressions when JSX syntax is used in
.js
files. -
#7311
62154b9
Thanks @qraqras! - Added the new nursery rulenoUselessCatchBinding
. This rule disallows unnecessary catch bindings.try {// Do something} catch (unused) {}} catch {} -
#7349
45c1dfe
Thanks @ematipico! - Fixed #4298. Biome now correctly formats CSS declarations when it contains one single value:.bar {--123456789012345678901234567890: var(--1234567890123456789012345678901234567);--123456789012345678901234567890: var(--1234567890123456789012345678901234567);} -
#7295
7638e84
Thanks @ematipico! - Fixed #7130. Removed the emission of a false-positive diagnostic. Biome no longer emits the following diagnostic:lib/main.ts:1:5 suppressions/unused ━━━━━━━━━━━━━━━━━━━━━━━━━⚠ Suppression comment has no effect because the tool is not enabled.> 1 │ /** biome-ignore-all assist/source/organizeImports: For the lib root file, we don't want to organize exports */│ ^^^^^^^^^^^^^^^^ -
#7377
811f47b
Thanks @ematipico! - Fixed #7371 where the Biome Language Server didn’t correctly recompute the diagnostics when updating a nested configuration file. -
#7348
ac27fc5
Thanks @ematipico! - Fixed #7079. Now the ruleuseSemanticElements
doesn’t trigger components and custom elements. -
#7389
ab06a7e
Thanks @Conaclos! - Fixed #7344.useNamingConvention
no longer reports interfaces defined in global declarations.Interfaces declared in global declarations augment existing interfaces. Thus, they must be ignored.
In the following example,
useNamingConvention
reportedHTMLElement
. It is now ignored.export {};declare global {interface HTMLElement {foo(): void;}} -
#7315
4a2bd2f
Thanks @vladimir-ivanov! - Fixed #7310:useReadonlyClassProperties
correctly handles nested assignments, avoiding false positives when a class property is assigned within another assignment expression.Example of code that previously triggered a false positive but is now correctly ignored:
class test {private thing: number = 0; // incorrectly flaggedpublic incrementThing(): void {const temp = { x: 0 };temp.x = this.thing++;}}
2.2.4
Patch Changes
-
#7453
aa8cea3
Thanks @arendjr! - Fixed #7242: Aliases specified inpackage.json
’simports
section now support having multiple targets as part of an array. -
#7454
ac17183
Thanks @arendjr! - Greatly improved performance ofnoImportCycles
by eliminating allocations.In one repository, the total runtime of Biome with only
noImportCycles
enabled went from ~23s down to ~4s. -
#7447
7139aad
Thanks @rriski! - Fixes #7446. The GritQL$...
spread metavariable now correctly matches members in object literals, aligning its behavior with arrays and function calls. -
#6710
98cf9af
Thanks @arendjr! - Fixed #4723: Type inference now recognises index signatures and their accesses when they are being indexed as a string.Example
type BagOfPromises = {// This is an index signature definition. It declares that instances of type// `BagOfPromises` can be indexed using arbitrary strings.[property: string]: Promise<void>;};let bag: BagOfPromises = {};// Because `bag.iAmAPromise` is equivalent to `bag["iAmAPromise"]`, this is// considered an access to the string index, and a Promise is expected.bag.iAmAPromise; -
#7415
d042f18
Thanks @qraqras! - Fixed #7212, now theuseOptionalChain
rule recognizes optional chaining usingtypeof
(e.g.,typeof foo !== 'undefined' && foo.bar
). -
#7419
576baf4
Thanks @Conaclos! - Fixed #7323.noUnusedPrivateClassMembers
no longer reports as unused TypeScriptprivate
members if the rule encounters a computed access onthis
.In the following example,
member
as previously reported as unused. It is no longer reported.class TsBioo {private member: number;set_with_name(name: string, value: number) {this[name] = value;}} -
351bccd
Thanks @ematipico! - Added the new nursery lint rulenoJsxLiterals
, which disallows the use of string literals inside JSX.The rule catches these cases:
<><div>test</div> {/* test is invalid */}<>test</><div>{/* this string is invalid */}asdjfl test foo</div></> -
#7406
b906112
Thanks @mdevils! - Fixed an issue (#6393) where the useHookAtTopLevel rule reported excessive diagnostics for nested hook calls.The rule now reports only the offending top-level call site, not sub-hooks of composite hooks.
// Before: reported twice (useFoo and useBar).function useFoo() {return useBar();}function Component() {if (cond) useFoo();}// After: reported once at the call to useFoo(). -
#7461
ea585a9
Thanks @arendjr! - Improved performance ofnoPrivateImports
by eliminating allocations.In one repository, the total runtime of Biome with only
noPrivateImports
enabled went from ~3.2s down to ~1.4s. -
351bccd
Thanks @ematipico! - Fixed #7411. The Biome Language Server had a regression where opening an editor with a file already open wouldn’t load the project settings correctly. -
#7142
53ff5ae
Thanks @Netail! - Added the new nursery rulenoDuplicateDependencies
, which verifies that no dependencies are duplicated between thebundledDependencies
,bundleDependencies
,dependencies
,devDependencies
,overrides
,optionalDependencies
, andpeerDependencies
sections.For example, the following snippets will trigger the rule:
{"dependencies": {"foo": ""},"devDependencies": {"foo": ""}}{"dependencies": {"foo": ""},"optionalDependencies": {"foo": ""}}{"dependencies": {"foo": ""},"peerDependencies": {"foo": ""}} -
351bccd
Thanks @ematipico! - Fixed #3824. Now the option CLI--color
is correctly applied to logging too.
2.2.5 Latest
Patch Changes
-
#7597
5c3d542
Thanks @arendjr! - Fixed #6432:useImportExtensions
now works correctly with aliased paths. -
#7269
f18dac1
Thanks @CDGardner! - Fixed #6648, where Biome’snoUselessFragments
contained inconsistencies with ESLint for fragments only containing text.Previously, Biome would report that fragments with only text were unnecessary under the
noUselessFragments
rule. Further analysis of ESLint’s behavior towards these cases revealed that text-only fragments (<>A</a>
,<React.Fragment>B</React.Fragment>
,<RenamedFragment>B</RenamedFragment>
) would not havenoUselessFragments
emitted for them.On the Biome side, instances such as these would emit
noUselessFragments
, and applying the suggested fix would turn the text content into a proper JS string.// Ended up as: - const t = "Text"const t = <>Text</>// Ended up as: - const e = t ? "Option A" : "Option B"const e = t ? <>Option A</> : <>Option B</>/* Ended up as:function someFunc() {return "Content desired to be a multi-line block of text."}*/function someFunc() {return <>Content desired to be a multi-lineblock of text.<>}The proposed update was to align Biome’s reaction to this rule with ESLint’s; the aforementioned examples will now be supported from Biome’s perspective, thus valid use of fragments.
// These instances are now valid and won't be called out by noUselessFragments.const t = <>Text</>const e = t ? <>Option A</> : <>Option B</>function someFunc() {return <>Content desired to be a multi-lineblock of text.<>} -
#7498
002cded
Thanks @siketyan! - Fixed #6893: TheuseExhaustiveDependencies
rule now correctly adds a dependency that is captured in a shorthand object member. For example:useEffect(() => {console.log({ firstId, secondId });}, []);is now correctly fixed to:
useEffect(() => {console.log({ firstId, secondId });}, [firstId, secondId]); -
#7509
1b61631
Thanks @siketyan! - Added a new lint rulenoReactForwardRef
, which detects usages offorwardRef
that is no longer needed and deprecated in React 19.For example:
export const Component = forwardRef(function Component(props, ref) {return <div ref={ref} />;});will be fixed to:
export const Component = function Component({ ref, ...props }) {return <div ref={ref} />;};Note that the rule provides an unsafe fix, which may break the code. Don’t forget to review the code after applying the fix.
-
#7520
3f06e19
Thanks @arendjr! - Added new nursery rulenoDeprecatedImports
to flag imports of deprecated symbols.Invalid example
foo.js import { oldUtility } from "./utils.js";utils.js /*** @deprecated*/export function oldUtility() {}Valid examples
foo.js import { newUtility, oldUtility } from "./utils.js";utils.js export function newUtility() {}// @deprecated (this is not a JSDoc comment)export function oldUtility() {} -
#7457
9637f93
Thanks @kedevked! - Addedstyle
andrequireForObjectLiteral
options to the lint ruleuseConsistentArrowReturn
.This rule enforces a consistent return style for arrow functions. It can be configured with the following options:
style
: (default:asNeeded
)always
: enforces that arrow functions always have a block body.never
: enforces that arrow functions never have a block body, when possible.asNeeded
: enforces that arrow functions have a block body only when necessary (e.g. for object literals).
style: "always"
Invalid:
const f = () => 1;Valid:
const f = () => {return 1;};style: "never"
Invalid:
const f = () => {return 1;};Valid:
const f = () => 1;style: "asNeeded"
Invalid:
const f = () => {return 1;};Valid:
const f = () => 1;style: "asNeeded"
andrequireForObjectLiteral: true
Valid:
const f = () => {return { a: 1 };}; -
#7510
527cec2
Thanks @rriski! - Implements #7339. GritQL patterns can now use native Biome AST nodes using theirPascalCase
names, in addition to the existing TreeSitter-compatiblesnake_case
names.engine biome(1.0)language js(typescript,jsx)or {// TreeSitter-compatible patternif_statement(),// Native Biome AST node patternJsIfStatement()} as $stmt where {register_diagnostic(span=$stmt,message="Found an if statement")} -
#7574
47907e7
Thanks @kedevked! - Fixed 7574. The diagnostic message for the ruleuseSolidForComponent
now correctly emphasizes<For />
and provides a working hyperlink to the Solid documentation. -
#7497
bd70f40
Thanks @siketyan! - Fixed #7320: TheuseConsistentCurlyBraces
rule now correctly detects a string literal including"
inside a JSX attribute value. -
#7522
1af9931
Thanks @Netail! - Added extra references to external rules to improve migration for the following rules:noUselessFragments
&noNestedComponentDefinitions
-
#7597
5c3d542
Thanks @arendjr! - Fixed an issue wherepackage.json
manifests would not be correctly discovered when evaluating files in the same directory. -
#7565
38d2098
Thanks @siketyan! - The resolver can now correctly resolve.ts
,.tsx
,.d.ts
,.js
files by.js
extension if exists, based on the file extension substitution in TypeScript.For example, the linter can now detect the floating promise in the following situation, if you have enabled the
noFloatingPromises
rule.foo.ts
export async function doSomething(): Promise<void> {}bar.ts
import { doSomething } from "./foo.js"; // doesn't exist actually, but it is resolved to `foo.ts`doSomething(); // floating promise! -
#7542
cadad2c
Thanks @mdevils! - Added the rulenoVueDuplicateKeys
, which prevents duplicate keys in Vue component definitions.This rule prevents the use of duplicate keys across different Vue component options such as
props
,data
,computed
,methods
, andsetup
. Even if keys don’t conflict in the script tag, they may cause issues in the template since Vue allows direct access to these keys.Invalid examples
<script>export default {props: ["foo"],data() {return {foo: "bar",};},};</script><script>export default {data() {return {message: "hello",};},methods: {message() {console.log("duplicate key");},},};</script><script>export default {computed: {count() {return this.value * 2;},},methods: {count() {this.value++;},},};</script>Valid examples
<script>export default {props: ["foo"],data() {return {bar: "baz",};},methods: {handleClick() {console.log("unique key");},},};</script><script>export default {computed: {displayMessage() {return this.message.toUpperCase();},},methods: {clearMessage() {this.message = "";},},};</script> -
#7546
a683acc
Thanks @siketyan! - Internal data for Unicode strings have been updated to Unicode 17.0. -
#7497
bd70f40
Thanks @siketyan! - Fixed #7256: TheuseConsistentCurlyBraces
rule now correctly ignores a string literal with braces that contains only whitespaces. Previously, literals that contains single whitespace were only allowed. -
#7565
38d2098
Thanks @siketyan! - TheuseImportExtensions
rule now correctly detects imports with an invalid extension. For example, importing.ts
file with.js
extension is flagged by default. If you are using TypeScript with neither theallowImportingTsExtensions
option nor therewriteRelativeImportExtensions
option, it’s recommended to turn on theforceJsExtensions
option of the rule. -
#7581
8653921
Thanks @lucasweng! - Fixed #7470: solved a false positive fornoDuplicateProperties
. Previously, declarations in@container
and@starting-style
at-rules were incorrectly flagged as duplicates of identical declarations at the root selector.For example, the linter no longer flags the
display
declaration in@container
or theopacity
declaration in@starting-style
.a {display: block;@container (min-width: 600px) {display: none;}}[popover]:popover-open {opacity: 1;@starting-style {opacity: 0;}} -
#7529
fea905f
Thanks @qraqras! - Fixed #7517: theuseOptionalChain
rule no longer suggests changes for typeof checks on global objects.// oktypeof window !== "undefined" && window.location; -
#7476
c015765
Thanks @ematipico! - Fixed a bug where the suppression action fornoPositiveTabindex
didn’t place the suppression comment in the correct position. -
#7511
a0039fd
Thanks @arendjr! - Added nursery rulenoUnusedExpressions
to flag expressions used as a statement that is neither an assignment nor a function call.Invalid examples
f; // intended to call `f()` insteadfunction foo() {0; // intended to `return 0` instead}Valid examples
f();function foo() {return 0;} -
#7564
40e515f
Thanks @turbocrime! - Fixed #6617: improveduseIterableCallbackReturn
to correctly handle arrow functions with a single-expressionvoid
body.Now the following code doesn’t trigger the rule anymore:
[].forEach(() => void null);
Copyright (c) 2023-present Biome Developers and Contributors.