コンテンツにスキップ

ブログ

Biome v1.9 Anniversary Release

Today we’re excited to announce the release of Biome v1.9 and to celebrate the first anniversary of Biome 🎊 Let’s take a look back at the first year of Biome and then explore the new features in Biome 1.9.

We officially announced Biome on 29 August 2023. From its inception, Biome has been a free open source software driven by its community. We have a governance and a solid base of contributors to ensure the longevity of the project.

In October 2023, one of the creators of Prettier launched the Prettier challenge that rewarded any project written in Rust that passes at least 95% of the Prettier tests for JavaScript. The aim of this challenge was to create a fast competitor to Prettier in order to stimulate improvements in Prettier’s performance. We quickly organized ourselves to get there as soon as possible. By the end of November, we surpassed this goal by passing 97% of the Prettier tests for JavaScript, as well as TypeScript, JSX and TSX! The Biome formatter is really fast: it can format a large code base in less than 1 second. In the process, we identified several formatting issues in Prettier. This has also pushed contributions to Prettier that greatly improved its performance. This challenge was a win for the whole web ecosystem!

By winning the challenge, we brought Biome to light. Many developers were excited to discover a fast alternative to Prettier, but also a fast alternative to ESLint! The approach of bundling both a formatter and a linter in one tool provides a unified and consistent experience with minimal configuration. Biome has been quickly adopted by many projects, including big ones such as Ant Design, Astro, Sentry, daisyUI, Refine, Discord, Pulumi, Label Studio, Spicetify, Apify, Slint, Rspack, FluidFramework, and others. Biome surpassed 2.7 million monthly NPM downloads in August 2024.

Biome monthly NPM downloads

We gained sponsorship, notably Shiguredo, l2BEAT, Phoenix Labs, KANAME, Nanabit, Vital, CodeRabbit, and Forge42. These sponsorships have helped move the project forward by rewarding contributors and even paying for maintenance work in recent months. We would like to reward and encourage more contributions, then if you use Biome, please consider sponsoring us!

We also gained many new contributors. Contributors who have made a significant contribution are regularly invited to join the Biome team. We started with a team of 5 core contributors, and we are now a team of 8 core contributors and 10 maintainers.

In June 2024, Biome won the JSNation’s productivity booster Open Source Award.

As we celebrate Biome’s first year, we’re pleased to announce the release of Biome 1.9, which brings many new features and bug fixes.

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

Terminal window
biome migrate --write

Stable CSS formatter and linter

Section titled Stable CSS formatter and linter

We are thrilled to announce that Biome’s CSS formatter and linter are now considered stable and are **enabled by default **. Do note that Biome only parses **standard CSS syntax ** so far, and doesn’t yet handle CSS dialects such as SCSS. As this is brand new functionality, you may also still run into some rough edges. Please report any problems you encounter!

The CSS linter provides 15 stable lint rules that were ported from stylelint:

It also provides the following nursery lint rules:

If you don’t want Biome to format and lint your CSS files, you can disable the CSS formatter and linter in the Biome configuration file:

{
"css": {
"formatter": {
"enabled": false
},
"linter": {
"enabled": false
}
}
}

or on the command line:

Terminal window
biome format --css-formatter-enabled=false
biome lint --css-linter-enabled=false
biome check --css-formatter-enabled=false --css-linter-enabled=false

Special thanks to Denis Bezrukov @denbezrukov, Jon Egeland @faultyserver and Yoshiaki Togami @togami2864 for coordinating and implementing most of the features related to CSS.

Stable GraphQL formatter and linter

Section titled Stable GraphQL formatter and linter

Another brand new feature: Biome now formats and lints GraphQL files by default.

For now, Biome provides only two nursery lint rules:

If you don’t want Biome to format and lint your GraphQL files, you can disable the GraphQL formatter and linter in the Biome configuration file:

{
"graphql": {
"formatter": {
"enabled": false
},
"linter": {
"enabled": false
}
}
}

or on the command line:

Terminal window
biome format --graphql-formatter-enabled=false
biome lint --graphql-linter-enabled=false
biome check --graphql-formatter-enabled=false --css-linter-enabled=false

Special thanks to Swan that funded the implementation of the GraphQL formatter and to Võ Hoàng Long @vohoanglong0107 for implementing most of the features related to GraphQL.

Back in February, one of our Core Contributors published a proposal for plugin support. One of the highlights was the use of GritQL as a foundation for our plugin system.

GritQL is a powerful query language that lets you do structural searches on your codebase. This means that trivia such as whitespace or even the type of string quotes used will be ignored in your search query. It also has many features for querying the structure of your code, making it much more elegant for searching code than regular expressions.

Integrating a query language such as GritQL is no easy feat, and throughout the year we published multiple status updates. Today, we release the first product of this effort: A new biome search command.

While we believe this command may already be useful to users in some situations (especially when it gets integrated in our IDE extensions!), this command is really a stepping stone towards our plugin efforts. By allowing our users to try it out in a first iteration, we hope to gain insight into the type of queries you want to do, as well as the bugs we need to focus on.

For now, the search command is explicitly marked as **EXPERIMENTAL **, since many limitations are yet to be fixed or explored. Keep this in mind when you try it out, and please let us know what you think! For an overview of specific limitations, please see the dedicated issue.

Even though there are still plenty of limitations, we do believe the integration has progressed far enough that we can shift our focus towards the integration of actual plugins. We cannot yet promise a timeline, but we’ll keep you posted!

PS.: GritQL escapes code snippets using backticks, but most shells interpret backticks as command invocations. To avoid this, it’s best to put single quotes around your Grit queries. For instance, the following command search for all console.log invocations:

Terminal window
biome search '`console.$method($args)` where { $method <: or { `log`, `info` } }' ./
./benchmark/bench.js:38:3 search ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  38 │ 	console.info(`\n⌛ repository: ${name}`);

./packages/@biomejs/js-api/scripts/update-nightly-version.mjs:27:1 search ━━━━━━━━━━━━━━

  27 │  console.log(`version=${version}`);

Searched 67 files in 1034ms. Found 2 matches.

Special thanks to Grit for open-sourcing GritQL, Arend van Beelen @arendjr for integrating the GritQL engine into Biome, and to @BackupMiles for implementing the formatting of search results in the biome search command!

Biome is now able to take the .editorconfig of your project into account. This is an opt-in feature. You have to turn it on in your Biome configuration file:

biome.json
{
"formatter": {
"useEditorconfig": true
}
}

Note that all options specified in the Biome configuration file override the ones specified in .editorconfig. For now, only the .editorconfig at the root of your project is taken into account.

Special thanks to Carson McManus @dyc3 for implementing this feature!

JavaScript formatter and linter

Section titled JavaScript formatter and linter

We updated the JavaScript formatter to match Prettier v3.3. The most significant change is adding parentheses around nullish coalescing in ternaries. This change adds clarity to operator precedence.

// Input
foo ? bar ?? foo : baz;
// Biome 1.8.3 and Prettier 3.3.2
foo ? bar ?? foo : baz;
// Biome 1.9 and Prettier 3.3.3
foo ? (bar ?? foo) : baz;

Regarding the linter, we stabilized the following lint rules:

We added the following new rules:

And we deprecated the following rules:

Our linter has now more than 250 rules! Most of the ESLint rules and rules from some plugins have been ported. We are close to completing the port of ESLint.

For the full list of changes, please refer to our changelog.

Nicolas Hedger @nhedger is working on a new version of our first-party VSCode plugin. This new version will improve workspace support and fix some long-standing issues.

During this first year, we have discovered a number of issues that cannot be solved without introducing small breaking changes. For example, we rely on a glob library that sometimes doesn’t behave as users expect. We feel it is time to address these long-standing issues. Following our versioning philosophy, these small breaking changes cannot be made without releasing a major release. Therefore, the next release of Biome will be a major release: Biome 2.0. We will use this opportunity to remove deprecated features. We will make the migration smooth by using the biome migrate command.

Biome v1.7

Today we’re excited to announce the release of Biome v1.7!

This new version provides an easy path to migrate from ESLint and Prettier. It also introduces experimental machine-readable reports for the formatter and the linter, new linter rules, and many fixes.

Update Biome using the following commands:

npm install --save-dev --save-exact @biomejs/biome@latest
npx @biomejs/biome migrate

Migrate from ESLint with a single command

Section titled Migrate from ESLint with a single command

This release introduces a new subcommand biome migrate eslint. This command will read your ESLint configuration and attempt to port their settings to Biome.

The subcommand is able to handle both the legacy and the flat configuration files. It supports the extends field of the legacy configuration and loads both shared and plugin configurations! The subcommand also migrates .eslintignore.

Given the following ESLint configuration:

.eslintrc.json
{
"extends": ["plugin:unicorn/recommended"],
"plugins": ["unicorn"],
"ignore_patterns": ["dist/**"],
"globals": {
"Global1": "readonly"
},
"rules": {
"eqeqeq": "error"
},
"overrides": [
{
"files": ["tests/**"],
"rules": {
"eqeqeq": "off"
}
}
]
}

And the following Biome configuration:

biome.json
{
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
}
}

Run biome migrate eslint --write to migrate your ESLint configuration to Biome. The command overwrites your initial Biome configuration. For example, it disables recommended. This results in the following Biome configuration:

biome.json
{
"organizeImports": { "enabled": true },
"linter": {
"enabled": true,
"rules": {
"recommended": false,
"complexity": {
"noForEach": "error",
"noStaticOnlyClass": "error",
"noUselessSwitchCase": "error",
"useFlatMap": "error"
},
"style": {
"noNegationElse": "off",
"useForOf": "error",
"useNodejsImportProtocol": "error",
"useNumberNamespace": "error"
},
"suspicious": {
"noDoubleEquals": "error",
"noThenProperty": "error",
"useIsArray": "error"
}
}
},
"javascript": { "globals": ["Global1"] },
"overrides": [
{
"include": ["tests/**"],
"linter": { "rules": { "suspicious": { "noDoubleEquals": "off" } } }
}
]
}

The subcommand needs Node.js to load and resolve all the plugins and extends configured in the ESLint configuration file. For now, biome migrate eslint doesn’t support configuration written in YAML.

We have a dedicated page that lists the equivalent Biome rule of a given ESLint rule. We handle some ESLint plugins such as TypeScript ESLint, ESLint JSX A11y, ESLint React, and ESLint Unicorn. Some rules are equivalent to their ESLint counterparts, while others are inspired. By default, Biome doesn’t migrate inspired rules. You can use the CLI flag --include-inspired to migrate them.

Migrate from Prettier with a single command

Section titled Migrate from Prettier with a single command

Biome v1.6 introduced the subcommand biome migrate prettier.

In Biome v1.7, we add support of Prettier’s overrides and attempts to convert .prettierignore glob patterns to globs supported by Biome.

During the migration, Prettier’s overrides is translated to Biome’s overrides. Given the following .prettierrc.json

.prettierrc.json
{
"useTabs": false,
"singleQuote": true,
"overrides": [
{
"files": ["*.json"],
"options": { "tabWidth": 2 }
}
]
}

Run biome migrate prettier --write to migrate your Prettier configuration to Biome. This results in the following Biome configuration:

biome.json
{
"formatter": {
"enabled": true,
"formatWithErrors": false,
"indentStyle": "space",
"indentWidth": 2,
"lineEnding": "lf",
"lineWidth": 80,
"attributePosition": "auto"
},
"organizeImports": { "enabled": true },
"linter": { "enabled": true, "rules": { "recommended": true } },
"javascript": {
"formatter": {
"jsxQuoteStyle": "double",
"quoteProperties": "asNeeded",
"trailingComma": "all",
"semicolons": "asNeeded",
"arrowParentheses": "always",
"bracketSpacing": true,
"bracketSameLine": false,
"quoteStyle": "single",
"attributePosition": "auto"
}
},
"overrides": [
{
"include": ["*.json"],
"formatter": {
"indentWidth": 2
}
}
]
}

The subcommand needs Node.js to load JavaScript configurations such as .prettierrc.js. biome migrate prettier doesn’t support configuration written in JSON5, TOML, or YAML.

Biome is now able to output JSON reports detailing the diagnostics emitted by a command.

For instance, you can emit a report when you lint a codebase:

Terminal window
biome lint --reporter=json-pretty .

For now, we support two report formats: json and json-pretty.

Note that the report format is **experimental **, and it might change in the future. Please try this feature and let us know if any information needs to be added to the reports.

Biome v1.5 added the --changed to format and lint git tracked files that have been changed.

Today we are introducing a new option --staged which allows you to check only files added to the Git index (staged files). This is useful for checking that the files you want to commit are formatted and linted:

Terminal window
biome check --staged .

This is handy for writing your own pre-commit script. Note that unstaged changes on a staged file are not ignored. Thus, we still recommend using a dedicated pre-commit tool.

Thanks to @castarco for implementing this feature!

Since Biome v1.6, we added several new rules. New rules are incubated in the nursery group. Nursery rules are exempt from semantic versioning.

The new rules are:

Once stable, a nursery rule is promoted to a stable group. The following rules are promoted:

  • By default, Biome searches a configuration file in the working directory and parent directories if it doesn’t exist. Biome provides a CLI option --config-path and an environment variable BIOME_CONFIG_PATH that allows which can be used to override this behavior. Previously, they required a directory containing a Biome configuration file. For example, the following command uses the Biome configuration file in ./config/.

    Terminal window
    biome format --config-path=./config/ ./src

    This wasn’t very clear for many users who are used to specifying the configuration file path directly. They now accept a file, so the following command is valid:

    Terminal window
    biome format --config-path=./config/biome.json ./src
  • You can now ignore React imports in the rules noUnusedImports and useImportType by setting javascript.jsxRuntime to reactClassic.

  • Biome applies specific settings to well-known files. It now recognizes more files and distinguishes between JSON files that only allow comments and JSON files that allow both comments and trailing commas.

  • In the React ecosystem, files ending in .js are allowed to contain JSX syntax. The Biome extension is now able to parse JSX syntax in files that are associated with the JavaScript language identifier.

  • useExhaustiveDependencies now supports Preact.

See the changelog for more details.

We have started work on the CSS formatter and linter. Early implementation towards a plugin system is also underway. Some of our contributors have started preliminary work for GraphQL and YAML. Any help is welcome!

If Biome is valuable to you or your company, consider donating monthly to our Open Collective. You can also sponsor us on GitHub. This is important for the sustainability of the project.

Follow us on our Twitter and join our Discord community.

Biome v1.6

Update Biome using the following commands:

Terminal window
npm install --save-dev --save-exact @biomejs/biome@latest
npx @biomejs/biome migrate

Partial support for Astro, Svelte and Vue files

Section titled Partial support for Astro, Svelte and Vue files

In this release, we’re happy to provide partial support for Astro, Svelte and Vue files. What does partial support mean?

While the team is working on a unified data structure for HTML-ish languages, we discovered that we could provide Biome functionalities to those files with just a few changes, albeit with some limitations.

This means that Biome is able to analyze the JavaScript/TypeScript portion of said files, and all features are available: formatting, linting and import sorting! Here’s an example of what you should expect in terms of developer experience:

Screenshot of Biome linting in action for an Astro file in VSCode

Make sure to read the documentation about expectations and limitations.

Configuration, lighter and more powerful

Section titled Configuration, lighter and more powerful

Biome now accepts the biome.jsonc file as configuration! You can insert all the comments you want in there.

From this version, Biome can use the extends property to resolve other configuration files that are inside installed dependencies.

There are few important steps in order to make the configuration discoverable. The file must be exported from a "module" package, and the file should be exported in your package.json like this:

{
"name": "@shared-configs",
"type": "module",
"exports": {
"./biome": "./biome.json"
}
}

This set up allows to expose a specifier @shared-configs/biome, which you use inside your biome.json file.

{
"extends": ["@shared-configs/biome"]
}

The resolution of the dependencies is powered by the library oxc-resolver, one of the many libraries provided by the OXC project. It’s battle-tested and spec compliant!

We reduced the size our configuration by a factor of 6.5! This change might not have massive effects on the speed of the program, but it greatly reduced the memory used when running the CLI or the LSP.

Other than fixes, the formatter provides two new options that should improve the compatibility with Prettier.

When formatter.attributePosition has the value multiline, all attributes of HTML-ish languages (JSX/TSX as for time of writing) will be collapsed on multiple lines regardless of their numbers:

With variant auto (default)

The attributes are automatically formatted, and they will collapse in multiple lines only when they hit certain criteria.

file.jsx
<Button as="link" style="primary" href="https://example.com">
Hit me
</Button>

With variant multiline

The attributes are always formatted on multiple lines, regardless.

file.jsx
<Button
as="link"
style="primary"
href="https://example.com"
>
Hit me
</Button>

The contributor @octoshikari implemented this new feature by themselves! Huge thank you for helping the Biome project.

Option json.formatter.trailingCommas

Section titled Option json.formatter.trailingCommas

Previously, Biome parser introduced an option that would allow to parse JSON and JSONC files that contained a trailing comma. This was required to ease the friction caused by other tools that tolerate trailing commas by default (e.g. VSCode, Prettier, etc.).

Unfortunately, our formatter wasn’t as tolerant. But with this release, we’ve introduced the option json.formatter.trailingCommas. It allows you to apply the same rules as with js.formatter.trailingComma.

With variant none (default)

The formatter removes the trailing comma upon formatting.

file.json
{
"lorem": "ipsum",
"lorem": "ipsum",
"lorem": "ipsum",
"lorem": "ipsum_last"
}

With variant all

The formatter adds the trailing comma upon formatting.

file.json
{
"lorem": "ipsum",
"lorem": "ipsum",
"lorem": "ipsum",
"lorem": "ipsum_last",
}

Easier migration from Prettier

Section titled Easier migration from Prettier

This release introduces a new command called biome migrate prettier. This command will read your Prettier .prettierrc/prettier.json and .prettierignore, and attempt to port its options and globs in Biome.

Given a prettier.json file, Biome will modify the existing configuration file to match Prettier’s options:

prettier.json
{ "useTabs": false, "semi": true, "singleQuote": true }
biome.json
{
"formatter": {
"enabled": true,
"formatWithErrors": false,
"indentStyle": "space",
"indentWidth": 2,
"lineEnding": "lf",
"lineWidth": 80,
"attributePosition": "auto"
},
"linter": { "enabled": true },
"javascript": {
"formatter": {
"jsxQuoteStyle": "double",
"quoteProperties": "asNeeded",
"trailingCommas": "all",
"semicolons": "always",
"arrowParentheses": "always",
"bracketSpacing": true,
"bracketSameLine": false,
"quoteStyle": "single",
"attributePosition": "auto"
}
}
}

New rules are incubated in the nursery group. Once stable, we promote them to a stable group. The following rules are promoted:

Additionally, the following rules are now recommended:

  • Remove nursery/useGroupedTypeImport. The rule style/useImportType covers the behavior of this rule.

New rules are now available:

  • We drastically reduced the number of protected files, which means you can now format your package.json, tsconfig.json, etc. with Biome. Lock files are still considered protected.
  • The CLI now does a better job at reporting the total number of files and the files that were really changed.
  • When a diagnostic shows a file name on the terminal that is integrated with your editor, you can click it and the editor will open the file for you.
  • The command biome rage now accepts two nice options: --formatter and --linter.
  • We removed some superfluous error diagnostic when running the biome check command.

Roadmap 2024

We are thrilled to share what the Core Contributors and Maintainers would like to focus on in 2024.

We want to remind you that Biome is a community-driven project, so we can only promise that some of the ideas outlined below will be shipped.

However, if you’re excited about some aspects of the project, and you want to see some of them developed faster than others, you can help us in many ways:

The project is young and can’t compete against giants such as Prettier, ESLint, Webpack, Vite, ESBuild, etc. However, the recent events (sponsors, bounty challenge, Biome being a fork of Rome) showed that the users have interest in the project, and we showed those users that we have the tools to fulfil a need.

Moving small projects from ESLint/Prettier is easy, but moving **big ** code bases is challenging and time-consuming; this is a big friction point in Biome.

Users have different needs, though, so it will only be possible to satisfy some of them. We want to ensure that all features and contributions to our project embrace our philosophy and provide the best experience by default.

  1. Help users to move to Biome
  2. Expand Biome’s language support so Biome tools can span more of the web ecosystem
  3. Deepen Biome’s existing capabilities to offer more functionalities
  4. Plugins
  5. Transformations
  6. Community and content
  • Offer guides on our website to users who want to migrate from Prettier (CLI commands and configuration)
  • Offer guides on our website to users who want to migrate from ESlint (CLI commands and configuration)
  • Offer a section on our website that shows a mapping of the ESLint rules to our rules
  • Offer commands to ease the transition
    • A command called biome migrate prettier that will read .prettierrc and .prettierignore will update the biome.json file (or create it) with the configuration from the Prettier files.
    • A command called biome migrate eslint will read the JSON configuration of Eslint and the ignore file. There will be expectations and limitations.

Expand Biome’s language support

Section titled Expand Biome’s language support

CSS is our next language of focus, and we are making good progress. HTML and Markdown will follow. Follow our up-to-date page to keep up with the progress of our work.

The CSS language will enable much work and experimentation: CSS formatting and linting, and we will port some of the lint rules from stylelint. A new area of experimentation is cross-linting.

The idea of cross-linting can be explained with an example: compute the CSS styles/classes defined in a project and warn a user when said styles aren’t used inside JSX/HTML files.

Plus, we unlock another area of experimentation, which is embedded formatting.

HTML and Markdown will be our next languages of focus. HTML will enable us to parse other variants of HTML that are popular in the frontend ecosystem: Vue, Svelte and Astro, and this would require some exploration of how to represent super languages of HTML.

Deepen Biome’s existing capabilities to offer more functionalities.

Section titled Deepen Biome’s existing capabilities to offer more functionalities.
  • Project analysis and dependency resolution
  • Type system
  • CLI

Project analysis and dependency resolution

Section titled Project analysis and dependency resolution

We will provide lint rules to read the manifest and detect errors such as invalid licenses.

With project resolution, we will be able to provide more lint rules, some of which will be able to detect unused modules.

With dependency resolution, we can - for example - detect dependencies that aren’t used inside a project.

With this infrastructure, our LSP is going to be more powerful and provide more features, for example:

  • rename variables across a project;
  • auto-complete for imports;
  • in-line types

Building a full-fledged type system such as TypeScript is a massive effort; that’s why we decided to take a different direction and start by building a subset of the type system that requires stricter typing. This approach would allow us to build some important lint rules that users have been asking for.

This will come with a downside: we will have to rely on a stricter code and minimal type inference from the compiler.

Once we have something we can rely on, we can slowly widen the capabilities of our type system.

More features for the command line tool, such as:

  • Add the explain command for offline documentation;
  • Allow the output to be exported in different formats (JSON, etc.)
  • Auto-completion for other shells such as zsh;
  • Implement the --modified argument, which allows to format - for example - only the modified lines of a document;
  • Expose metrics for Biome’s operations and being able to track down possible performance bottlenecks;

We will explore plugins and come up with a design that fits Biome. Biome is different from other tools because Biome is a toolchain that has multiple tools in it, so we have to think out of the box and propose a design that might differ from the tools people are used to.

We don’t know yet what a Biome’s plugin will look like, although a plugin should be able to tap all the tools that Biome offers.

Some ideas that we will consider:

  • DSL
  • WASM
  • A Runtime

Transformations and code generation will be our first steps towards our compiler.

We will provide the ability to transform TypeScript and JSX files into JavaScript files.

Biome has a growing ecosystem, with an official VSCode extension, an official IntelliJ extension, and a Discord bot. We want to grow the features these tools provide and welcome anyone who wants to help us.

Our community is slowly growing, and we want to reward everyone who sticks around and contributes to Biome. At Biome, * *we value every contribution **, so you don’t need to be proficient in Rust to help us. Even participating in discussions and helping us to shape our features or helping other people are considered contributions. If you’d like to continue contributing to our ecosystem, we also encourage you to nominate yourself as a maintainer of the project.

Recently Biome started its own YouTube Channel. We will use this channel to share learning content with the community.

With this blog post, we also want to officially announce our new logo, homepage and rebranding of the website.

With this new logo, we want to give a different meaning to the project. Biome **isn’t ** a fork of Rome anymore, but a self-sufficient project ready to bloom.

The triangle of the logo represents the mountains - **soil ** -, and the curly shape on the bottom left represents a wave of the ocean - **water **. Two elements that are important in creating a self-sufficient ecosystem, so it can thrive and grow.

Biome v1.5

Along with the Roadmap for 2024, the new logo and homepage, we also published a new version. This version has few features around the CLI and many fixes in our formatter. Our TypeScript, JSX and JavaScript formatting has surpassed the 97% compatibility rate with Prettier. Biome now provides over 190 lint rules.

Update Biome using the following commands:

Terminal window
npm install --save-dev --save-exact @biomejs/biome@latest
npx @biomejs/biome migrate
  • Process only the files that were changed.
  • The command biome ci now prints diagnostics in GitHub PRs.
  • A new command,biome explain.
  • The command biome migrate updates the $schema.
  • New lint rules.

Process only the files that were changed

Section titled Process only the files that were changed

If you enable the integration with VCS, you can tell Biome to process only the files that were changed. As for now, this feature computes the files that were changed by using a VCS, so Biome doesn’t know exactly which lines changed.

This feature practically makes some utilities such as lint-staged obsolete.

To take advantage of this feature, you have to tell Biome what’s the default branch in the configuration file, and then you’ll have to pass the option --changed via CLI:

biome.json
{
"vcs": {
"enabled": true,
"clientKind": "git",
"defaultBranch": "main"
}
}

Once you modified some files, use the new option to the command you need, for example the format command:

Terminal window
biome format --changed --write

The command biome ci now prints diagnostics in GitHub PRs

Section titled The command biome ci now prints diagnostics in GitHub PRs

For quite some time, users were confused by the difference between the commands check and cibecause, until now, their behaviours have been very similar. From this version, the command ci can detect the GitHub CI environment and print annotation in the PRs.

Screenshot of a GitHub annotation printed by Biome

It’s possible that you would need to change your permissions of your workflow files in case you don’t see the annotations:

.github/workflows/action.yml
permissions:
pull-requests: write

This command will serve as an “offline” documentation tool. In this release, the command supports the explanation of all the lint rules; for example you can request documentation for noAccumulatingSpread:

Terminal window
biome explain noAccumulatingSpread

Which will print the following Markdown:

# noAccumulatingSpread
No fix available.
This rule is recommended.
# Description
Disallow the use of spread (`...`) syntax on accumulators.
Spread syntax allows an iterable to be expanded into its individual elements.
Spread syntax should be avoided on accumulators (like those in `.reduce`)
because it causes a time complexity of `O(n^2)` instead of `O(n)`.
Source: https://prateeksurana.me/blog/why-using-object-spread-with-reduce-bad-idea/
## Examples
### Invalid
```js,expect_diagnostic
var a = ['a', 'b', 'c'];
a.reduce((acc, val) => [...acc, val], []);
```
```js,expect_diagnostic
var a = ['a', 'b', 'c'];
a.reduce((acc, val) => {return [...acc, val];}, []);
```
```js,expect_diagnostic
var a = ['a', 'b', 'c'];
a.reduce((acc, val) => ({...acc, [val]: val}), {});
```
## Valid
```js
var a = ['a', 'b', 'c'];
a.reduce((acc, val) => {acc.push(val); return acc}, []);
```

We plan to make this output more readable for terminals, as well as provide autocompletion for this command.

The command biome migrate updates the $schema

Section titled The command biome migrate updates the $schema

The command biome migrate now updates the $schema value inside the configuration file biome.json if you avail of the online schema. Run this command as soon as you update to Biome v1.5.0:

biome.json
{
"$schema": "https://biomejs.dev/schemas/1.4.1/schema.json"
"$schema": "https://biomejs.dev/schemas/1.5.0/schema.json"
}
interface I {
}
export {I};
nursery/useExportType.js:2:8 lint/nursery/useExportType  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   All exports are only types and should thus use export type.

    1 │ interface I {}
  > 2 │ export { I };
          ^^^^^^
    3 │ 

   Using export type allows transpilers to safely drop exports of types without looking for their definition.

   Safe fix: Use a grouped export type.

    2 │ export·type·{·I·};
         +++++
import {A} from "./mod.js";
type TypeOfA = typeof A;
let a: A;
nursery/useImportType.js:1:1 lint/nursery/useImportType  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   All these imports are only used as types.

  > 1 │ import { A } from "./mod.js";
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    2 │ type TypeOfA = typeof A;
    3 │ let a: A;

   Importing the types with import type ensures that they are removed by the transpilers and avoids loading unnecessary modules.

   Safe fix: Use import type.

    1 │ import·type·{·A·}·from·"./mod.js";
         +++++

Enforces naming conventions for JavaScript and TypeScript filenames.

import fs from 'fs';
nursery/useNodejsImportProtocol.js:1:16 lint/nursery/useNodejsImportProtocol  FIXABLE  ━━━━━━━━━━━━━━━━━

   Import from Node.js builtin module "fs" should use the "node:" protocol.

  > 1 │ import fs from 'fs';
                  ^^^^
    2 │ 

   Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.

   Unsafe fix: Change to "node:fs".

    1  - import·fs·from·'fs';
      1+ import·fs·from·"node:fs";
    2 2

import fs from "fs";
import path from "node:path";
nursery/noNodejsModules.js:1:16 lint/nursery/noNodejsModules ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   Using Node.js modules are forbidden.

  > 1 │ import fs from "fs";
                  ^^^^
    2 │ import path from "node:path";
    3 │ 

   Can be useful for client-side web projects that do not have access to those modules.

   Remove the import module.

function f() {
console.log(x);
const x;
}
nursery/noInvalidUseBeforeDeclaration.js:3:11 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   Const declarations must have an initialized value.

    1 │ function f() {
    2 │     console.log(x);
  > 3 │     const x;
             ^
    4 │ }
    5 │ 

   This variable needs to be initialized.

eval("var a = 0");
nursery/noGlobalEval.js:1:1 lint/nursery/noGlobalEval ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   eval() exposes to security risks and performance issues.

  > 1 │ eval("var a = 0");
   ^^^^
    2 │ 

   See the MDN web docs for more details.

   Refactor the code so that it doesn't need to call eval().

Object = null;
nursery/noGlobalAssign.js:1:1 lint/nursery/noGlobalAssign ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   A global variable should not be reassigned.

  > 1 │ Object = null;
   ^^^^^^^
    2 │ 

   Assigning to a global variable can override essential functionality.

/^[Á]$/u;
nursery/noMisleadingCharacterClass.js:1:1 lint/nursery/noMisleadingCharacterClass ━━━━━━━━━━━━━━━━━━

   Unexpected combined character in the character class.

  > 1 │ /^[Á]$/u;
   ^^^^^^^^
    2 │ 

const foo = {
then() {
}
};
nursery/noThenProperty.js:2:5 lint/nursery/noThenProperty ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   Do not add then to an object.

    1 │ const foo = {
  > 2 │     then() {}
       ^^^^
    3 │ };
    4 │ 

const foo = {
get then() {
}
};
var a = x ? true : true;
nursery/noUselessTernary.js:1:9 lint/nursery/noUselessTernary ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

   Unnecessary use of boolean literals in conditional expression.

  > 1 │ var a = x ? true : true;
           ^^^^^^^^^^^^^^^
    2 │ 

   Simplify your code by directly assigning the result without using a ternary operator.

   If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
     Check for more details about NOT operator.