Repository navigation
2.6.8
Patch Changes
-
#13080
a68137dThanks @dyc3! - Added the nursery rulenoBufferConstructor, which disallows the deprecated Node.jsBuffer()andnew Buffer()constructors. UseBuffer.from(),Buffer.alloc(), orBuffer.allocUnsafe()instead.new Buffer(5);
-
#12966
82651f5Thanks @dyc3! - Added the nursery rulenoConfusingArraySplice, which reportssplice()andtoSpliced()calls that replace a single element or insert at index-1.array.splice(index, 1, element); // use `array[index] = element` instead
-
#12924
0a9d204Thanks @dyc3! - Added the nursery rulenoDynamicRequire, which disallowsrequire()calls whose module name is built at runtime. When thecheckDynamicImportsoption is enabled, the rule also checksimport()calls.require("./locales/" + language);
-
#12907
6f2635aThanks @dyc3! - Added the nursery rulenoLateCurrentTargetAccess, which reports reads ofevent.currentTargetthat run after the browser has finished handling the event, whencurrentTargetisnull.element.addEventListener("click", async (event) => { await save(); event.currentTarget.disabled = false; });
-
#12904
04f30c4Thanks @dyc3! - Added the nursery rulenoMisusedSpread, which uses type information to report spreads that produce unexpected results: strings spread into arrays or arguments, and promises, functions, maps, arrays, iterables, class instances, and classes spread into objects or JSX attributes.declare function getUser(): Promise<{ name: string }>; const user = { ...getUser() };
-
#12893
5d7ca32Thanks @dyc3! - Added the nursery rulenoTripleSlashReference, which reports/// <reference path="..." />comments and/// <reference types="..." />comments for packages that the file also imports. Thelib,path, andtypesoptions control which kinds of references are allowed./// <reference path="./globals.d.ts" /> -
#12561
746c421Thanks @dyc3! - Added the nursery rulenoVueAsyncComputed, which reports asynchronous code in Vue computed properties, such asasyncfunctions,await, promises,setTimeout(), andnextTick().<script> export default { computed: { async user() { return fetchUser(this.userId); }, }, }; </script>
-
#12964
149d729Thanks @dyc3! - Added the nursery rulenoVueDefineModelDefault, which disallows thedefaultoption in Vue'sdefineModel(). When a parent component passesundefinedwithv-model, the child component uses the default value while the parent keepsundefined, so the two components show different values.<script setup> const model = defineModel({ type: String, default: "" }); </script>
-
#13060
67bc9d5Thanks @dyc3! - Added the nursery rulenoVueDeprecatedFilter, which reports the filter syntax that Vue 3 removed.For example, the following template uses the
currencyfilter:<template> <p>{{ price | currency }}</p> </template>
-
#12545
0bbe4f1Thanks @dyc3! - Added the new nursery rulenoVueDeprecatedVIs, which reports the deprecated Vuev-isdirective. Use theisattribute with avue:prefix instead.<template> <div v-is="'MyComponent'"></div> </template>
-
#12580
3fdc987Thanks @dyc3! - Added the nursery rulenoVueExportInScriptSetup, which disallowsexportin Vue<script setup>blocks. Vue fails to compile a component when its<script setup>block exports a value. TypeScript type exports are allowed.<script setup> export const message = "Hello"; </script>
-
#13063
d4e90c8Thanks @dyc3! - Added the nursery rulenoYamlEmptyMapKeys, which reports YAML map entries whose key is missing, or has only a tag or an anchor. The rule is recommended.: value -
#13061
97aa183Thanks @dyc3! - Added the nursery rulenoYamlEmptyMapValues, which reports keys in YAML maps that have no value.name: -
#13062
6aad75fThanks @dyc3! - Added the new nursery rulenoYamlEmptySequenceEntries, which reports empty items in YAML lists.fruits: - apple - - banana
-
#13082
c1c8c85Thanks @dyc3! - Added the nursery ruleuseCalledWith, which reportstoHaveBeenCalled(),toBeCalled(), andtoHaveBeenCalledOnce()assertions, because they don't check the arguments that the function was called with. The rule belongs to thetestdomain.expect(sendEmail).toHaveBeenCalled();
-
#13075
acfeaf9Thanks @dyc3! - Added the nursery ruleuseExpectToHaveBeenCalled, which reports tests that compare the number of calls of a mock function to zero, and suggests usingtoHaveBeenCalled()instead.expect(sendEmail).toHaveBeenCalledTimes(0);
-
#13076
cf5b1a6Thanks @dyc3! - Added the nursery ruleuseExpectToHaveBeenCalledTimes, which reports tests that check the length ofmock.callswithtoHaveLength(), and suggests usingtoHaveBeenCalledTimes()instead.expect(onSave.mock.calls).toHaveLength(1);
-
#13020
5d28641Thanks @dyc3! - Added the new nursery ruleusePackageJsonValidLicense, which reports alicensefield inpackage.jsonthat isn't a valid license. The rule accepts SPDX license identifiers and expressions,UNLICENSED, and references to a license file such asSEE LICENSE IN LICENSE.md.For example, the rule reports the following
package.jsonfile becauseGPL3isn't an SPDX license identifier:{ "name": "my-package", "license": "GPL3" } -
#13079
058d7a1Thanks @dyc3! - Added the nursery ruleuseSpyOn, which reports properties that are overwritten withjest.fn()orvi.fn(). Overwriting a property loses its original value, whilejest.spyOn()andvi.spyOn()keep it so it can be restored after the test.Date.now = jest.fn(() => 10);
-
#13081
be58f67Thanks @dyc3! - Added the nursery ruleuseTopLevelRequire, which reportsrequire()calls that aren't at the top level of the module, such as calls inside functions, blocks, ortrystatements.function readFile(filename, callback) { const fs = require("fs"); fs.readFile(filename, callback); }
-
#13054
4d81f0dThanks @dyc3! - Added the nursery ruleuseValidNamespaceImports, which reports names read from a namespace import that the imported module doesn't export. It also reports assignments to members of a namespace import, and namespace imports of modules that have no exports.import * as utils from "./utils.js"; utils.subtract(2, 1); // `./utils.js` doesn't export `subtract`
-
#13058
ae251e4Thanks @dyc3! - Added the new nursery ruleuseVueConsistentVOnHandlerStyle, which enforces one style of event handler in Vuev-ondirectives. By default, it prefers the name of a method, and an inline function where a method name can't be used.<template> <button @click="save()">Save</button> </template>
-
#12965
c33c03dThanks @dyc3! - Added the nursery ruleuseVueRegisteredComponentNameCasing, which requires the names of components registered in thecomponentsoption of a Vue component to use one casing style. By default, names must be in PascalCase. Thecasingoption switches the rule to camelCase or kebab-case.<script> export default { components: { "todo-item": TodoItem, }, }; </script>
-
#12145
596a2b1Thanks @ematipico! - Added type narrowing for unwritten locallet/constvariables and parameters aftertypeof, equality, nullish, and truthiness checks. Type-aware rules now use these refinements in branches, short-circuit expressions, and after early returns, includingnoUnnecessaryConditionsandnoFloatingPromises. Types such as{}no longer imply that a value is always truthy. -
#12935
e506ff1Thanks @dyc3! - Improved the performance of the rulesnoRedeclareandnoUnsafeDeclarationMerging.biome lintwith Biome's default rules is now about 3% to 5% faster on large projects, and up to 11% faster on some TypeScript projects. -
#13181
e1556aeThanks @dyc3! - Fixed the HTML formatter printing a comment twice when it ends the line of an element's opening tag. For example,<div><!-- comment -->followed by<i>x</i></div>on the next line is now formatted as:- <div><!-- comment --> + <div> <!-- comment --> <i>x</i> </div>
-
#13130
1b350edThanks @dyc3! - Fixed #13107: the unsafe fix ofnoDistractingElementsnow removes the whole element, including its closing tag and children, instead of only the opening tag. The fix is no longer offered when removing the element would produce invalid code, such asconst Ticker = () => <marquee>News</marquee>;. -
#13054
4d81f0dThanks @dyc3! - FixednoUnresolvedImportsreporting names that a module re-exports from a CommonJS module or from a file that isn't JavaScript, such asexport { foo } from "./legacy.cjs". The rule now also reports default imports from a module that only re-exports another module withexport * from, becauseexport * fromdoesn't forward the default export. -
#12602
d5da394Thanks @dyc3! - Fixed #12600:biome lint --suppressnow adds suppression comments for diagnostics emitted by plugins, such as// biome-ignore lint/plugin/noFoo: ignored using `--suppress`. -
#13097
3be9e3dThanks @ashokram-si! - Fixed #13064: ThenoUnknownTypeSelectorrule now correctly accepts the valid<selectedcontent>HTML element used in customizable select controls. -
#13181
e1556aeThanks @dyc3! - Fixed #13167: The HTML formatter no longer deletes comments that follow a Svelte block delimiter on the same line, such as{#if},{:else}, or{#each}. For example,{#if a}<!-- comment --><i>x</i>{/if}is now formatted as:{#if a} - <i>x</i> + <!-- comment --><i>x</i> {/if} -
#12845
e3ab04dThanks @dyc3! - Fixed the location of Tailwind CSS diagnostics reported on unquoted object keys. Inclsx({ shadow: active }), diagnostics now highlightshadowinstead of starting one character later athadow:. -
#13098
d3be626Thanks @ashokram-si! - Fixed #13084: TheuseThisInClassMethodsrule now correctly recognizesthiswhen used inside parameter default values for methods, setters, and class fields. -
#13131
a788cacThanks @dyc3! - Fixed #13129: the fix ofuseArrowFunctionno longer produces invalid code when the function is in the initializer of aforstatement and returns aninexpression. The arrow function body is now wrapped in parentheses.// Before for (let has = function (k) { return k in cache; }; ;) {} // After the fix for (let has = (k) => (k in cache); ;) {}
-
#12840
8908627Thanks @dyc3! - Fixed #12796:useMathMinMaxno longer reports comparisons with abigintwritten as an expression, such as-1nor2n ** 62n - 1n, or with aconstvariable initialized with one. Its unsafe fix turned these comparisons intoMath.min()orMath.max()calls, which throw aTypeErrorwhen given abigint.const MAX = 2n ** 62n - 1n; const clamp = (x) => (x > MAX ? MAX : x);
-
#13152
61924f6Thanks @dyc3! - FixednoVueWatchAfterAwait,noVueLifecycleAfterAwaitandnoVueRestrictedCallAfterAwait, which now also check thesetup()function passed as the first argument ofdefineComponent(). The following code is now reported:import { defineComponent, onMounted } from "vue"; defineComponent(async (props) => { await load(); onMounted(() => {}); }, { props: ["id"] });
When
defineComponent()receives both a function and an options object, these rules now ignore thesetupoption, because Vue runs the function instead. -
#13152
61924f6Thanks @dyc3! -noVueDuplicateKeysnow checks the properties returned by asetup()method of an options object, soreturn { foo }conflicts with a prop, data property, method or computed property namedfoo. -
#13152
61924f6Thanks @dyc3! - The Vue emit rules now read events declared with a function type, as indefineEmits<(e: "change", value: string) => void>(), and event names written as template literals without substitutions, as inemit(`change`).noVueUndeclaredEmits,noVueUnusedEmitDeclarations,useVueSingleEventPayloadanduseVueEmitValidatorpreviously skipped events declared in these forms.noVueShadowNativeEventsnow checksthis.$emit()only wherethisis the component, and no longer reports$emit()called through a variable that holdsthis, as inconst vm = this; vm.$emit("click"). -
#12947
a54965dThanks @machadinhos! - Added the nursery rulenoDrizzleDbObjectInsideTransaction, which reports a Drizzle ORM instance used inside its own transaction callback instead of the transaction object.await db.transaction(async (tx) => { await db.insert(users).values({ name: "John" }); });
-
#13123
e7c8297Thanks @ematipico! - Fixed #12176: type-aware rules now select the matching overload of a method declared several times in an interface or object type. For example,useAwaitThenableno longer reportsawait app.listen({ port: 0 })on a Fastify server, and still reportsawait app.listen({ port: 0 }, callback). -
#12059
87784c7Thanks @dyc3! - FixednoUnsafePlusOperandstreating the negation of abigintvalue as anumber. Code such as-value + 1n, wherevalueis declared asbigint, is no longer reported for mixingnumberandbigint. -
#13151
be372b5Thanks @dyc3! - Fixed Vue lint rules such asuseVueVModelanduseVueVOnExacttreating MathML elements like<math>and<mi>as components. Biome now recognizes the MathML Core elements as native elements, and in Vue, Svelte, and Astro files it treats known hyphenated elements such as<annotation-xml>and the SVG<font-face>as native elements instead of components. -
#12059
87784c7Thanks @dyc3! - Type inference now evaluates conditional types such asT extends U ? X : Y, includinginferand distribution over unions, instead of treating them as a union of both branches. This also applies to built-in types such asExclude,Extract,ReturnType,Parameters, andAwaited, which improves the accuracy of type-aware rules such asnoFloatingPromises.type Unwrap<T> = T extends Promise<infer U> ? U : T; // Previously inferred as `unknown | Promise<number>`, now as `number`. type Value = Unwrap<Promise<number>>;
-
#12602
d5da394Thanks @dyc3! - Biome now reports an error when a GritQL plugin file name contains invalid characters that could conflict with Biome suppressions. -
#12838
81d8d28Thanks @dyc3! - Added the nursery rulenoTailwindRestrictedClassesfor JavaScript and HTML. It reports the Tailwind CSS classes and variants listed in its options with a custom message, and can replace them with a configured class or variant.{ "linter": { "rules": { "nursery": { "noTailwindRestrictedClasses": { "level": "error", "options": { "classes": { "bg-green-500": { "message": "Use the success color.", "use": "bg-success" }, "float-*": "Use flexbox or grid for layout." } } } } } } }<div className="hover:bg-green-500 float-left" />; // both classes are reported
-
#12932
68e6887Thanks @dyc3! - Improved the performance of linting files that have no suppression comments by up to 61%. -
#13136
dcb1eabThanks @dyc3! - Improved the performance of linting JavaScript and HTML files when Tailwind rules are enabled. -
#13094
ae66383Thanks @dyc3! - Fixed #12994: the HTML formatter no longer moves a word onto its own line when it follows an inline element or{expression}that starts a line. Formatting such text is now stable after one pass.<span> Showing the first {shown} of - {total} - references + {total} references </span> -
#13162
854ff15Thanks @Punisheroot! - Fixed #13125:noUselessThisAliasno longer reports aliases used in instance and static class field initializers, where replacing the alias withthischanges which object is accessed. -
#12059
87784c7Thanks @dyc3! - Fixed type inference for the intersection of a primitive type and one of its literal types, such asstring & "a", which Biome inferred asneverinstead of"a". Type-aware rules such asuseExhaustiveSwitchCasesandnoFloatingPromisesnow see the literal, so the following switch is reported for missing the"a"case.type Kind = ("a" & string) | "b"; function handle(kind: Kind) { switch (kind) { case "b": break; } }
-
#12551
ca039a1Thanks @pkallos! - Fixed #9842:useNullishCoalescingno longer skips||and||=inside a call to a locally declaredBooleanwhenignoreBooleanCoercionis enabled.
What's Changed
- fix(lint/js): count this in parameter defaults in useThisInClassMethods by @ashokram-si in #13098
- chore(deps): update dependency @types/node to v24.19.2 by @renovate[bot] in #13046
- fix(lint): check Boolean is global in useNullishCoalescing by @pkallos in #12551
- chore: delete weird files by @ematipico in #13117
- feat(type_inference): support conditional types and
inferbindings by @dyc3 in #12059 - docs(lint/css): skip Sass-evaluated math functions in useBaseline by @vibbix in #12974
- feat(types): add flow-sensitive narrowing foundations by @ematipico in #12145
- feat(types): narrow explicit local predicate calls by @ematipico in #12146
- feat(types): narrow after standalone assertion calls by @ematipico in #12147
- feat(lint): add noVueDeprecatedVIs by @dyc3 in #12545
- feat(lint): add noTailwindRestrictedClasses by @dyc3 in #12838
- feat(lint): add noTripleSlashReference by @dyc3 in #12893
- feat(lint): add noMisusedSpread by @dyc3 in #12904
- feat(lint): add noLateCurrentTargetAccess by @dyc3 in #12907
- feat(lint): add noDynamicRequire by @dyc3 in #12924
- feat(lint): add noVueDefineModelDefault by @dyc3 in #12964
- feat(lint): add noConfusingArraySplice by @dyc3 in #12966
- feat(lint): add useVueRegisteredComponentNameCasing by @dyc3 in #12965
- feat(lint): add usePackageJsonValidLicense by @dyc3 in #13020
- fix(inference): overload in local inference by @ematipico in #13123
- docs: typo in static value doc comments by @ninglinLiu in #13132
- chore(deps): update to rust 1.100, add minimum release age config by @dyc3 in #13124
- fix(noDistractingElements): remove the whole element in the unsafe fix by @dyc3 in #13130
- fix(useArrowFunction): parenthesize
inbodies in for initializers by @dyc3 in #13131 - fix(useMathMinMax): trace bindings a little further to figure out if the arguments are bigints by @dyc3 in #12840
- perf(inference): queries and namespace by @ematipico in #13126
- chore: update rule metadata by @dyc3 in #13134
- perf(package): sublinear SPDX licence lookup by @dyc3 in #13138
- perf(lint): implement visited_kinds() for tailwind class string query, simplify it by @dyc3 in #13136
- perf(html): add token set for mathml elements by @dyc3 in #13151
- refactor(lint): make old vue rules use the new vue semantic model by @dyc3 in #13152
- feat(lint): add noDrizzleDbObjectInsideTransaction by @machadinhos in #12947
- fix(format/html): keep words after inline elements on the same line by @dyc3 in #13094
- fix(lint/css): recognize the selectedcontent element in noUnknownTypeSelector by @ashokram-si in #13097
- fix(analyze): emit suppression actions for plugin diagnostics by @dyc3 in #12602
- feat(lint): add useVueConsistentVOnHandlerStyle by @dyc3 in #13058
- feat(lint): add noVueDeprecatedFilter by @dyc3 in #13060
- feat(lint): add noYamlEmptyMapValues by @dyc3 in #13061
- feat(lint): add noYamlEmptyMapKeys by @dyc3 in #13063
- feat(lint): add noYamlEmptySequenceEntries by @dyc3 in #13062
- feat(lint): add useExpectToHaveBeenCalled by @dyc3 in #13075
- feat(lint): add useExpectToHaveBeenCalledTimes by @dyc3 in #13076
- feat(lint): add useSpyOn by @dyc3 in #13079
- feat(lint): add noBufferConstructor by @dyc3 in #13080
- feat(lint): add useTopLevelRequire by @dyc3 in #13081
- feat(lint): add useCalledWith by @dyc3 in #13082
- feat(lint): add noVueExportInScriptSetup by @dyc3 in #12580
- feat(lint): add useValidNamespaceImports by @dyc3 in #13054
- feat(lint): add noVueAsyncComputed by @dyc3 in #12561
- fix(tailwind): locate classes in unquoted object keys correctly by @dyc3 in #12845
- chore(deps): ignore js-sys crate in renovate config by @dyc3 in #13182
- fix(format/html/svelte): keep comments after block delimiters and opening tags by @dyc3 in #13181
- fix(lint): preserve this aliases in class field initializers by @Punisheroot in #13162
- perf(lint): locate binding nodes near the query node in noRedeclare by @dyc3 in #12935
- perf(analyze): skip the suppression token pass in files without suppression comments by @dyc3 in #12932
- fix(format/html): print comment before suppressed first child once by @dyc3 in #13189
- docs(skills): improve comments writing by @ematipico in #13197
- docs(skill): improve writing style by @ematipico in #13198
- ci: release by @github-actions[bot] in #13104
New Contributors
- @machadinhos made their first contribution in #12947
Full Changelog: https://github.com/biomejs/biome/compare/@biomejs/biome@2.6.7...@biomejs/biome@2.6.8