Pular para o conteúdo

Blog

Biome v2.0 beta

After hard work from our team, Biome’s long-awaited 2.0 release is nearing completion. It will be packed with many large features, so we would like your help testing it with a public beta!

If you would like to try it out, you can update Biome and migrate your configuration using the following commands:

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

Also, make sure you use the prereleases of our IDE extensions. The stable versions of our extensions are not yet prepared for Biome 2.0!

Documentation for the upcoming release can be found at https://next.biomejs.dev/.

While the final 2.0 release may still have small changes in its final feature set, here’s what you can expect in the beta:

  • Plugins: You can write custom lint rules using GritQL.
  • Domains: Domains help to group lint rules by technology, framework, or well, domain. Thanks to domains, your default set of recommended lint rules will only include those that are relevant to your project.
  • Multi-file analysis: Lint rules can now apply analysis based on information from other files, enabling rules such as noImportCycles.
  • noFloatingPromises: Still a proof-of-concept, but our first type-aware lint rule is making an appearance.
  • Our Import Organizer has seen a major revamp.
  • Assists: Biome Assist can provide actions without diagnostics, such as sorting object keys.
  • Improved suppressions: Suppress a rule in an entire file using // biome-ignore-all, or suppress a range using // biome-ignore-start and // biome-ignore-end.
  • HTML formatter: Still in preview, this is the first time we ship an HTML formatter.
  • Many, many, fixes, new lint rules, and other improvements.

Biome 2.0 comes with our first iteration of Linter Plugins.

These plugins are still limited in scope: They allow for matching code snippets and reporting diagnostics on them.

Here is an example of a plugin that reports on all usages of Object.assign():

`$fn($args)` where {
$fn <: `Object.assign`,
register_diagnostic(
span = $fn,
message = "Prefer object spread instead of `Object.assign()`"
)
}

It’s a first step, but we have plenty of ideas for making them more powerful, and we’ll eagerly hear from our users on what they would like to see prioritised.

We’ve introduced a new linter feature: Domains.

Domains are a new way to organise lint rules by technology, framework, or well, domain. Right now, we have identified four domains:

  • next: Rules related to Next.js.
  • react: Rules related to React.
  • solid: Rules related to Solid.js.
  • test: Rules related to testing, regardless of framework or library.

You can enable and disable rules that belong to a domain together:

biome.jsonc
{
"linter": {
"domains": {
"test": "all", // all rules that belong to this domain are enabled
"react": "recommended", // only the recommended rules from this domain are enabled
"solid": "none" // rules related to Solid are disabled
}
}
}

But it gets better: Biome will automatically inspect your package.json and determine which domains should be enabled by default. For instance, if you have react defined as one of your dependencies, the default setting for the react domain automatically becomes recommended.

This way, Biome’s total set of recommended rules should be most relevant to your specific project needs.

And finally, domains can add global variables to the javascript.globals setting. This should make Biome even easier to setup.

Before version 2.0, Biome lint rules could only operate on one file at a time. This brought us far, but many of the more interesting rules require information from other files too.

To accomplish this, we have added a file scanner to Biome that scans all the files in your project and indexes them, similar to what an LSP service might do in your IDE. We’re not going to beat around the bush: Scanning projects means that Biome has become slower for many projects. But we do believe the ability to do multi-file analysis is worth it. And without a scanner, multi-file analysis would become even slower, as rules would need to perform ad-hoc file system access individually.

That said, this is a beta, and there are certainly more opportunities to improve our scanner and its performance. If you have a repository where you feel our performance became unacceptably slow, please reach out and file an issue.

For now, we have a few interesting rules that can make use of our multi-file analysis:

  • noImportCycles is able to look at import statements and detect cycles between them.
  • noPrivateImports is a new rule based on the useImportRestrictions nursery rule from Biome 1.x, and inspired by ESLint’s plugin-import-access. It forbids importing symbols with an @private JSDoc tag from other modules, and forbids importing symbols with an @package tag if the importing file is not in the same folder or one of its subfolders.
  • useImportExtensions has been improved because it can now determine the actual extension that needs to be used for an import, instead of guessing based on hueristics.

Finally, we’ve also designed the multi-file analysis with monorepos in mind. While full monorepo support may not make it in time for the 2.0 release, we expect to be able to deliver more on this front soon.

With Biome’s linter we have always strived to provide a battery-included approach to linting. This means we’re not just aiming to replace ESLint, but also its plugins. One of the hardest plugins to replace is typescript-eslint.

Biome has featured some rules from typescript-eslint for a while now, but we could never replace all rules, because they relied on type information for their analysis. And in order to get type information, typescript-eslint relies on tsc itself, which is rather slow and also complicates setup.

This is about to change. With Biome 2.0, we’re introducing a first version of the noFloatingPromises rule, one of the most-requested rules that relies on type information. In fairness, we should not consider it more than a proof-of-concept right now, because there are some notable limitations to its capabilities:

  • It doesn’t understand complex types yet.
  • It cannot do type inference yet.
  • It can currently only analyse types that occur in the same file.

Still, its capabilities are sufficient to catch some of the low-hanging fruit. Consider this small snippet:

example.js
async function returnsPromise() { /* ... */ }
returnsPromise().then(() => {});

It will trigger the following diagnostic:

example.js:3:1 lint/nursery/noFloatingPromises ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ A “floating” Promise was found, meaning it is not properly handled and could lead to ignored errors or unexpected behavior.
1 │ async function returnsPromise() { /* ... */ }
2 │
> 3 │ returnsPromise().then(() => {});
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5 │
ℹ This happens when a Promise is not awaited, lacks a .catch or .then rejection handler, or is not explicitly ignored using the void operator.

As you can guess, we intend to expand this rule’s capabilities over time. And with our new multi-file analysis in place, we expect to be able to make serious strides with this. Stay tuned for more announcements on this front!

In Biome 1.x, our Import Organizer had several limitations:

  • Groups of imports or exports would be considered separate chunks, meaning they would be sorted independently. This meant the following didn’t work as expected:

    example.js
    import { lib2 } from "library2";
    import { util } from "./utils.js";
    import { lib1 } from "library1";

    It would correctly sort "library1" to be placed above "./utils.js", but it wouldn’t be able to carry it over the newline to the top. What we got was this:

    organizer_v1.js
    import { lib2 } from "library2";
    import { lib1 } from "library1";
    import { util } from "./utils.js";

    But instead, what we really wanted was this:

    organizer_v2.js
    import { lib1 } from "library1";
    import { lib2 } from "library2";
    import { util } from "./utils.js";
  • Separate imports from the same module wouldn’t be merged. Consider the following example:

    example.js
    import { util1 } from "./utils.js";
    import { util2 } from "./utils.js";

    Nothing would be done to merge these import statements, whereas what we would have wanted was this:

    organizer_v2.js
    import { util1, util2 } from "./utils.js";
  • No custom ordering could be configured. Maybe you didn’t really like the default approach of ordering by “distance” from the source file that you’re importing from. Maybe you wanted to organise like this:

    organizer_v2.js
    import { open } from "node:fs";
    import { internalLib1 } from "@company/library1";
    import { internalLib2 } from "@company/library2";
    import { lib1 } from "library1";

In Biome 2.0, all these limitations are lifted. In fact, if you look at the examples above, all snippets labeled organizer_v2.js can be produced just like that by our new import organizer.

Other improvements include support for organizing export statements, support for “detached” comments for explicitly separating import chunks if necessary, and import attribute sorting.

You can find the documentation on the new import organizer at https://next.biomejs.dev/assist/actions/organize-imports/.

The Import Organizer was always a bit of a special case in Biome. It was neither part of the linter, nor of the formatter. This was because we didn’t want it to show diagnostics the way the linter does, while its organizing features went beyond what we expect from the formatter.

In Biome 2.0, we have generalised such use cases in the form of Biome Assist. The assist is meant to provide actions, which are similar to the fixes in lint rules, but without the diagnostics.

The Import Organizer has become an assist, but we’ve started using this approach for new assists too: useSortedKeys can sort keys in object literals, while useSortedAttributes can sort attributes in JSX.

For more information about assists, see: https://next.biomejs.dev/assist/

In addition to the // biome-ignore comments we already supported, we now support // biome-ignore-all for suppressing a lint rule or the formatter in an entire file.

We also added support for suppression ranges using // biome-ignore-start and // biome-ignore-end. Note that // biome-ignore-end is optional in case you want to let a range run until the end of the file.

For more information about suppressions, see: https://next.biomejs.dev/linter/#suppress-lint-rules

After a few months of hard work, we are happy to announce that the HTML formatter is now ready for users to try out and start reporting bugs! This is a huge step towards Biome fully supporting HTML-ish templating languages used in frameworks like Vue and Svelte.

The HTML formatter only touches actual .html files for now, so no formatting of html in .vue or .svelte files yet. It also won’t format embedded languages like JavaScript or CSS yet. HTML’s options like attributePosition, bracketSameLine, and whitespaceSensitivity have been implemented.

The HTML formatter is still pretty experimental, so it will remain disabled by default for the full 2.0 release. At the time of writing, Biome is able to parse the grand majority of Prettier’s HTML tests, and format 46/124 of them correctly. Despite not matching Prettier yet, we’re pretty confident that it should output documents that are formatted adequately without destroying anything. If you find a case where it doesn’t, please let us know!

You can enable the HTML formatter by adding the following to your config file:

{
"html": {
"formatter": {
"enabled": true
}
}
}

Several new rules have added since v1.9:

  • BREAKING: The configuration fields include and ignore have been replaced with a single includes field.
  • BREAKING: Reworked some recommended rules recommended to be less pedantic and blocking. This is a breaking change if your project relied on those rules to block the CI in case of violations. If you used the migrate command, the behaviour should remain as before.
  • BREAKING: The style rules aren’t recommended anymore. If you used the migrate command, the behaviour should remain as before.
  • BREAKING: Removed deprecated rules:
    • noConsoleLog
    • noInvalidNewBuiltin
    • noNewSymbol
    • useShorthandArrayType
    • useSingleCaseStatement
  • BREAKING: Many deprecated options, including some that still referenced the old Rome name, have been removed.
  • Added a new option javascript.parser.jsxEverywhere to control whether Biome should expect JSX syntax in .js/.mjs/.cjs files.
  • Improved monorepo support: The rule noUndeclaredDependencies now works correctly in monorepos by using the nearest package.json file, instead of only the root one.
  • We have enabled support for .editorconfig files by default.
  • Changed default formatting of package.json to align better with formatting by package managers.

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

Roadmap 2025 and Biome 2.0

Today we’re happy to share our plans for Biome 2.0 as well as the rest of our roadmap for 2025. But before we dive into what’s coming, let’s do a quick recap of the major developments in 2024.

2024 was a great year for Biome. Let’s see what happened:

  • We released 4 new “minor” Biome versions, from 1.6 through 1.9, with plenty of useful features:
    • New biome search and biome explain commands, while the biome migrate command was significantly expanded to help users coming from ESLint and Prettier.
    • Added support for CSS and GraphQL formatting and linting.
    • Partial support for Astro, Svelte and Vue files.
    • The ability to let configuration files extend from one another, which is especially useful in monorepo and larger organizational setups.
    • Custom reporters for better CI integration and machine-readable output.
    • Support for .editorconfig.
    • We added countless new lint rules and miscellaneous fixes and improvements, with a special shoutout to useSortedClasses that marks the beginning of dedicated Tailwind support.
  • Our team of maintainers has grown from 10 members at the start of 2024 to 18 today.
  • We won the Productivity Booster award of the OS Awards 2024.
  • We gained several new sponsors.
  • We improved our IDE support on multiple fronts:
    • A new Zed extension has been contributed to the project.
    • Our VS Code extension has seen an overhaul that’s currently in Pre-Release.
    • And even though this happened after the new year, we shouldn’t neglect to mention that our IDEA plugin has seen a major update too, which is now available in the nightly channel.

One more thing that we are happy to announce is that as of January 2025, we are also offering Enterprise Support for Biome. Hopefully this will allow some of our contributors to spend more of their time and effort towards Biome!

Right now our team is busy preparing for the Biome 2.0 release. Because our project is still run by volunteer contributors, we do not have an ETA for you. But we can share some of the goodies that will be coming:

  • Plugins. A long-requested feature, we started the development of Biome plugins after an RFC process that started in January 2024. Biome 2.0 will feature the first fruits of this labor: Users will be able to create their own lint rules using GritQL.
  • Domains. Domains are a configuration feature that makes it easy for users to enable or disable all rules related to a specific domain, such as React, Next.js or testing frameworks. It also allows Biome to automatically enable recommended domain-specific rules based on the dependencies listed in your package.json.
  • Monorepo Support. While support for monorepos was already improved with our extends feature in biome.json, many weak spots remained. Biome 2.0 has an improved architecture based on an internal ProjectLayout that should resolve most of these.
  • Suppressions. Biome already allowed suppression of linter diagnostics through the use of // biome-ignore suppression comments. With Biome 2.0 we’re adding support for // biome-ignore-all and // biome-ignore-start/biome-ignore-end comments.
  • Multi-file analysis. Last but not least, we’re adding true Multi-file support to Biome 2.0. This means that our lint rules will be able to query information from other files, which will enable much more powerful lint rules.

Again, we should preface a disclaimer here: We’re a community-driven project, so we cannot promise to deliver any of the features below. But that doesn’t mean we don’t have a wishlist of things we would like to work on in 2025 😉

This year we will focus on:

  • HTML support. No toolchain for the web is complete without it, and we’re already working on it!
  • Embedded languages. CSS or GraphQL snippets inside a template literal in a JavaScript file? JavaScript or CSS inside an HTML file? Biome should be able to handle these as well, and we’ll try to make it happen. This should also lead to better support for Astro, Svelte, and Vue than we have today.
  • Type inference. This was already a wish for 2024, and we’re busy filling in the prerequisites such as multi-file analysis. There’s even an early proof-of-concept for a noFloatingPromises rule. This year we want to ship a real version of noFloatingPromises, and hopefully dabble further into type inference.
  • .d.ts generation. While we’re on the subject of types, we would also like to create our first transformation: generating .d.ts files from TypeScript sources. Initially we would only focus on TypeScript using Isolated Modules.
  • JSDoc support. Can we use JSDoc comments as a source of type information too? If we are able to do type inference, this seems an opportunity we cannot pass on.
  • Markdown support. Some work has already started for it and it would be a nice addition to round out our language support.
  • More plugins. While Biome 2.0 will launch with the ability to create lint rules in GritQL, that’s only the tip of the iceberg. We know our users want more, and we certainly have ideas for more types of plugins. We’ll first collect feedback from the 2.0 release, and then we’ll decide which plugin area we’ll focus on next.

We would like to thank our users and sponsors alike for their amazing support in 2024! Without you, this project would not be what it is today.

Hopefully we can also count on your support for the coming year. If you would like to help out, you can:

  • Become a contributor. Please help us to build those features!
  • Sponsor us. Ask your company to sponsor us: Biome is so fast that it can reduce your company’s CI times, improve developer productivity, and save money. Sponsorships also create exposure for your company.
  • Hire us. Is Biome missing anything that prevents your company from adopting it? You can make it happen by hiring us! Any company that hires a contributor to work on Biome for 3 months or more automatically applies for sponsorship benefits.
  • Improve our documentation. Write guides or recipes, or help to keep our translations up-to-date for non-English speakers.

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 BlueSky 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.