Перейти к содержимому

Biome v2.4—Embedded Snippets, HTML Accessibility, and Better Framework Support

Это содержимое пока не доступно на вашем языке.

The brand of the project. It says "Biome, toolchain of the web" The brand of the project. It says "Biome, toolchain of the web"

Biome v2.4 is the first minor release of the year! After more than ten patches from v2.3, today we bring to you a new version that contains many new features!

Once you have upgraded to Biome v2.4.0, migrate your Biome configuration to the new version by running the migrate command:

Terminal window
biome migrate --write

Among all the features shipped in this release, here are the ones we think you’re going to like most!

One of the most significant new features in Biome 2.4 is the ability to format and lint embedded CSS and GraphQL snippets within JavaScript files. Enable this experimental feature to automatically format and lint CSS and GraphQL code within template literals.

Biome recognizes CSS snippets from styled-components, Emotion, and similar CSS-in-JS libraries:

styled-components.js
import styled from "styled-components";
const Foo = styled.div`
display: flex;
color: red;
`;

GraphQL queries and mutations within JavaScript are now properly formatted and linted:

graphql-query.js
import gql from "graphql-tag";
const PeopleCountQuery = gql`
query PeopleCount {
allPeople {
totalCount
}
}
`;

To enable these features, add this to your configuration:

biome.json
{
"javascript": {
"experimentalEmbeddedSnippetsEnabled": true
}
}

Editors can now inject a Biome configuration to the Biome Language Server without affecting the project’s configuration.

If you have a Biome extension compatible with your LSP-ready editor, you can map inlineConfig. The configuration will be merged with the project’s configuration and it will take precedence.

In the following example, the editor won’t emit any diagnostics for the rule noConsole, but the CLI will still conform to the configuration of the project.

.zed/settings.json
{
"lsp": {
"biome": {
"settings": {
"inline_config": {
"linter": {
"rules": {
"suspicious": {
"noConsole": "off"
}
},
}
}
}
}
}
}

In Biome v2.3, we announced experimental full support for HTML-ish languages such as Vue, Svelte, and Astro. We’ve since focused on improving the developer experience based on community feedback. Several improvements were shipped in patch releases.

Biome 2.4 brings significantly improved parsing for Vue and Svelte, resulting in better formatting across the board. Additionally, the rules noUnusedVariables, useConst, useImportType and noUnusedImports have been substantially improved, so you will see fewer false positives.

All these improvements are visible only when the flag html.experimentalFullSupportEnabled is set to true. If you previously used the overrides configuration workaround to disable certain rules, you can now remove it. If you encounter false positives, please report them in this issue. We now have the infrastructure to address these problems.

The CSS parser can now parse Vue SFC syntax such as :slotted, :deep, and v-bind(), as well as :global and :local inside .astro, .svelte and .vue files.

Biome 2.4 introduces 15 comprehensive accessibility-focused lint rules for HTML, helping you build more accessible web applications:

These rules work seamlessly with Vue, Svelte, and Astro files. Please help us to ship more a11y rules.

The commands lint and check now have a --profile-rules flag. This flag enables the new internal profiler, which allows you to capture the execution time of lint rules, assist actions, and GritQL plugins.

The profiler tracks only the execution time of the rule, and it doesn’t track the time spent in querying Biome’s CST. The flag will print an output similar to this one:

Rule execution time (does not include any preprocessing)
total avg min max count rule
42.069ms 1.010µs 41.000ns 227.625µs 41633 correctness/noUnusedVariables
23.131ms 452.000ns 42.000ns 330.750µs 51096 suspicious/noFocusedTests
9.864ms 193.000ns 0.000ns 149.375µs 51046 suspicious/noConsole
8.074ms 198.000ns 0.000ns 141.208µs 40721 correctness/noUnusedFunctionParameters
7.963ms 137.000ns 0.000ns 263.958µs 57899 style/useNodejsImportProtocol
6.711ms 4.355µs 41.000ns 686.000µs 1541 source/organizeImports
4.076ms 664.000ns 0.000ns 132.792µs 6130 correctness/noUnusedImports
4.015ms 55.000ns 0.000ns 131.250µs 72343 correctness/noTypeOnlyImportAttributes
3.320ms 524.000ns 0.000ns 115.791µs 6334 style/useImportType
384.101µs 164.000ns 0.000ns 74.875µs 2328 correctness/noNodejsModules
384.042µs 2.782µs 42.000ns 163.417µs 138 correctness/noDuplicatePrivateClassMembers
10.753µs 282.000ns 83.000ns 833.000ns 38 correctness/noSuperWithoutExtends

One way to interpret the data is to check the rules/actions that have low counts, and check their execution time. For example, if the execution time feels way too high compared to what it should be, maybe it’s a good place to look for possible optimizations. Since we landed this feature, we have found some bottlenecks that we have fixed since then.

Biome 2.4 improves configuration file discovery in two major ways:

  1. Hidden configuration files: Biome now loads .biome.json and .biome.jsonc files. The loading order is: biome.jsonbiome.jsonc.biome.json.biome.jsonc

  2. Config home directories: Biome now attempts to load configuration files from platform-specific config directories:

    • $XDG_CONFIG_HOME or $HOME/.config/biome on Linux
    • /Users/$USER/Library/Application Support/biome on macOS
    • C:\Users\$USER\AppData\Roaming\biome\config on Windows

The priority order is: project folder (working directory) → parent folders → config home.

Biome 2.4 introduces the noDuplicateClasses assist action to detect and remove duplicate CSS classes.

For JSX files: Supports class, className attributes and utility functions like clsx, cn, cva.

For HTML files: Checks class attributes. This is the first assist action for HTML.

example.jsx
// Before
<div class="flex p-4 flex" />;
// After
<div class="flex p-4" />;

Thank you @mldangelo .

Added a new assist action useSortedInterfaceMembers that sorts TypeScript interface members for improved readability. It includes an autofix.

Before:

example.ts
interface MixedMembers {
z: string;
a: number;
(): void;
y: boolean;
}

After:

example.ts
interface MixedMembers {
a: number;
y: boolean;
z: string;
(): void;
}

Added groupByNesting option to the useSortedKeys assist. When enabled, object keys are grouped by their value’s nesting depth before sorting alphabetically.

Simple values (primitives, single-line arrays, and single-line objects) are sorted first, followed by nested values (multi-line arrays and multi-line objects).

biome.json
{
"linter": {
"rules": {
"source": {
"useSortedKeys": {
"options": {
"groupByNesting": true
}
}
}
}
}
}

Added ignore option to the useHookAtTopLevel rule. You can now specify function names that should not be treated as hooks, even if they follow the use* naming convention.

biome.json
{
"linter": {
"rules": {
"correctness": {
"useHookAtTopLevel": {
"options": {
"ignore": ["useDebounce", "useCustomUtility"]
}
}
}
}
}
}

useIterableCallbackReturn with checkForEach Option

Section titled “useIterableCallbackReturn with checkForEach Option”

The rule useIterableCallbackReturn now supports a checkForEach option. When set to false, the rule will skip checking for forEach() callbacks for returning values.

Updated useHookAtTopLevel to better catch invalid hook usage. The rule now generates diagnostics if:

  • A hook is used at the module level (top of the file, outside any function)
  • A hook is used within a function or method which is not a hook or component, unless it is a function expression (such as arrow functions commonly used in tests)

Added the extensionMappings option to useImportExtensions. This allows you to specify custom file extensions for different module types. For example, to ban all .ts imports in favor of .js imports:

biome.json
{
"linter": {
"rules": {
"nursery": {
"useImportExtensions": {
"level": "error",
"options": {
"extensionMappings": {
"ts": "js"
}
}
}
}
}
}
}

Added 2 options from typescript-eslint to useUnifiedTypeSignatures:

  • ignoreDifferentlyNamedParameters - Ignores overload signatures whose parameter names differ
  • ignoreDifferentJsDoc - Ignores overload signatures whose JSDoc comments differ

Added ignore option to noUnknownProperty, noUnknownFunction, noUnknownPseudoClass, and noUnknownPseudoElement. If an unknown property/function/selector name matches any of the items provided in ignore, a diagnostic won’t be emitted.

Improved the rule noUnusedVariables in Svelte files by correctly detecting variables defined in the JavaScript blocks and used inside the templates.

Biome 2.4 introduces a new linter domain called types. This domain enables all rules that require the type inference engine to function.

As opposed to the project domain (which only enables rules that require the module graph), the types domain specifically targets rules that need type information.

The following nursery rules have been moved to the types domain:

  • useArraySortCompare
  • useAwaitThenable
  • useFind
  • useRegexpExec
  • noUnnecessaryConditions
  • noMisusedPromises
  • noFloatingPromises

This allows you to enable or disable type-based linting more granularly using the --only and --skip flags.

Biome 2.4 promotes 24 nursery rules to stable groups, making them production-ready.

Promoted the following rules to the correctness group:

Promoted the following rules to the suspicious group:

Promoted the following rules to the complexity group:

Promoted the following rules to the style group:

Biome 2.4 can now format embedded CSS and GraphQL snippets within JavaScript files. See the Embedded snippets in JavaScript section in Highlights for details and examples.

Added the formatter option trailingNewline. When set to false, the formatter will remove the trailing newline at the end of formatted files. The default value is true, which preserves the current behavior.

This option is available globally and for each language-specific formatter configuration:

biome.json
{
"formatter": {
"trailingNewline": false
},
"javascript": {
"formatter": {
"trailingNewline": true
}
}
}

CLI flags are also available: --formatter-trailing-newline, --javascript-formatter-trailing-newline, --json-formatter-trailing-newline, etc.

Added support for the top-level suppression comment biome-ignore-all format: <explanation>. When placed at the beginning of the document, Biome won’t format the code.

generated.js
// biome-ignore-all format: generated
const a = [];
const b = [];

Formatting is now applied when applying safe/unsafe fixes via biome check. This ensures your code is properly formatted after applying automated fixes.

Added support for parsing and formatting the CSS @function at-rule from the CSS Mixins Module Level 1 specification:

styles.css
@function --transparent(--color <color>, --alpha <number>: 0.5) returns <color> {
result: oklch(from var(--color) l c h / var(--alpha));
}

Biome now automatically enables CSS modules parsing for *.module.css files. If your codebase only uses *.module.css files, you can remove the manual parser configuration.

Updated the CSS properties ordering to align with stylelint-config-recess-order v7.4.0, adding support for containment properties, font synthesis properties, ruby properties, color adjustment properties, view transitions properties, shapes properties, motion path properties, and more.

Added support for parsing :global and :local inside .astro, .svelte and .vue files, in the <style> portion of the file. This capability is only available when experimentalFullHtmlSupportEnabled is set to true.

Added --only and --skip options to biome check and biome ci, covering both lint diagnostics and assist actions. You can now run or exclude specific:

  • Lint rules
  • Assist actions
  • Groups of rules and actions
  • Domains (including the new types domain)

Examples:

Terminal window
biome check --only=suspicious/noDebugger src/**/*.js
biome ci --skip=project src/**
biome lint --only=types # Run only type-based rules

Multiple Reporters and Reporter Output to Files

Section titled “Multiple Reporters and Reporter Output to Files”

Biome 2.4 adds support for multiple reporters and the ability to save reporter output to arbitrary files.

If you run Biome on GitHub, you can now use both the default reporter and the GitHub reporter:

Terminal window
biome ci --reporter=default --reporter=github

With the new --reporter-file CLI option, it’s now possible to save the output of all reporters to a file:

Terminal window
biome ci --reporter=rdjson --reporter-file=/etc/tmp/report.json
biome ci --reporter=summary --reporter-file=./reports/file.txt

You can combine these two features. For example, have the default reporter written on terminal, and the rdjson reporter written on file:

Terminal window
biome ci --reporter=default --reporter=rdjson --reporter-file=/etc/tmp/report.json

The --reporter and --reporter-file flags must appear next to each other.

Added a new reporter --reporter=sarif, that emits diagnostics using the SARIF format. This is particularly useful for integrating Biome with security and code quality platforms.

Terminal window
biome ci --reporter=sarif --reporter-file=biome-results.sarif

Added new CLI options to the commands lsp-proxy and start that allow control over the Biome file watcher:

  • --watcher-kind (env: BIOME_WATCHER_KIND): Controls how the Biome file watcher behaves. Options: recommended (default), polling, or none.
  • --watcher-polling-interval (env: BIOME_WATCHER_POLLING_INTERVAL): The polling interval in milliseconds when using polling mode (defaults to 2000ms).

Revamped the logging options for all Biome commands. The commands format, lint, check, ci, search, lsp-proxy and start now accept consistent logging CLI options with environment variable aliases:

  • --log-file (env: BIOME_LOG_FILE) - Optional path/file to redirect log messages to
  • --log-prefix-name (env: BIOME_LOG_PREFIX_NAME) - Allows changing the prefix applied to the file name of the logs (daemon only)
  • --log-path (env: BIOME_LOG_PATH) - Allows changing the folder where logs are stored (daemon only)
  • --log-level (env: BIOME_LOG_LEVEL) - The level of logging: debug, info, warn, error, or none
  • --log-kind (env: BIOME_LOG_KIND) - What the log should look like

It’s now possible to provide the stacktrace for a fatal error. The stacktrace is only available when the environment variable RUST_BACKTRACE=1 is set:

Terminal window
RUST_BACKTRACE=1 biome lint

Added JSON as a target language for GritQL pattern matching. You can now write Grit plugins for JSON files, enabling:

  • Searching and transforming JSON configuration files
  • Enforcing patterns in package.json and other JSON configs
  • Writing custom lint rules for JSON using GritQL

Example patterns:

Match all key-value pairs:

pattern.grit
language json
pair(key = $k, value = $v)

Match objects with specific structure:

pattern.grit
language json
JsonObjectValue()

Supports both native Biome AST names (JsonMember, JsonObjectValue) and TreeSitter-compatible names (pair, object, array) for compatibility with existing Grit patterns.

For more details, see the GritQL documentation.

The Biome Language Server now reports progress while scanning files and dependencies in the project, providing better feedback during long-running operations.

Added support for Cursor files. When Biome sees a Cursor JSON file, it will parse it with comments enabled and trailing commas enabled:

  • $PROJECT/.cursor/
  • %APPDATA%\Cursor\User\ on Windows
  • ~/Library/Application Support/Cursor/User/ on macOS
  • ~/.config/Cursor/User/ on Linux

The Biome CSS parser is now able to parse Vue SFC syntax such as :slotted, :deep, and v-bind(). These pseudo-functions and directives are only correctly parsed when the CSS is defined inside .vue components.

This capability is only available when experimentalFullHtmlSupportEnabled is set to true.

Added e18e ESLint plugin as a recognized rule source. Six Biome rules now reference their e18e equivalents: useAtIndex, useExponentiationOperator, noPrototypeBuiltins, useDateNow, useSpread, and useObjectSpread.

In addition to the features highlighted above, Biome 2.4 includes numerous bug fixes, performance improvements, and smaller enhancements across the toolchain. For a complete list of changes, refer to the changelog page.

I like where this is going, how can I help?

Section titled “I like where this is going, how can I help?”

I want to remind you that Biome is a project led by volunteers who like programming, open-source, and embrace the Biome philosophy, so any help is welcome.

If you are familiar with Biome and would like to contribute to its outreach, you can assist us by translating the website into your native language. In this dashboard, you can check the supported languages and if they are up-to-date.

Join our Discord server, and engage with the community. Chatting with the community and being part of the community is a form of contribution.

If you like the technical aspects of the project, and you want to make your way into the Rust language, or practice your knowledge around parsers, compilers, analysers, etc., Biome is the project for you!

There are numerous aspects to explore; I assure you that you won’t get bored. Here is a small list of the things you can start with:

If you believe in the future of the project, you can also help with a financial contribution, via Open Collective or GitHub Sponsors.

Additionally, the project provides an enterprise support program where you as a company can employ one of the core contributors to work a specific aspect of the Biome toolchain.