# Biome > tagline: Biome not found. Check the URL or try using the search bar. --- --- title: '404' template: splash editUrl: false hero: title: '404' tagline: Biome not found. Check the URL or try using the search bar. --- --- --- title: VS Code extension V3 excerpt: Biome releases v3 of the VS Code extension authors: - nhedger date: 2025-04-29 cover: light: "@/assets/blog/roadmap-2024/banner-light.png" dark: "@/assets/blog/roadmap-2024/banner-dark.png" alt: The brand of the project. It says "Biome, toolchain of the web" socialImage: "@/assets/social-logo.png" --- We're excited to announce that version 3 of the Biome VS Code extension is now available! This release includes a range of new features and improvements to make your development experience even better: - 🗄️ Support for multi-root workspaces - 📝 Support for single-file mode - 👻 Support for unsaved files - 🔄 Automatic reload after updating Biome - ⚙️ Automatic reload after configuration changes - ✨ Improved status indicator ## Multi-root workspaces The Biome extension now supports [multi-root workspaces], so you can work on multiple projects side by side in a single VS Code window. Each workspace folder now runs its own independent Biome instance, keeping your projects isolated. :::caution[heads up for pre-release users] If you've been using the pre-release version over the past few months, please note that support for the `biome.projects` setting has been **removed** in the final release. We now recommend using **multiple workspace folders** instead to manage multiple projects. ::: [multi-root workspaces]: https://code.visualstudio.com/docs/editor/multi-root-workspaces ## Single-file mode Sometimes you just need to make a quick edit to _that one file_. The extension now fully supports **single-file mode**, making it easy to work with files that aren't part of a full project. ```sh frame="none" code that-one-file.js ``` To use this feature, make sure you have [Biome installed globally]. No worries if you forget, the extension will let you know if it can’t find Biome in your `PATH`. [Biome installed globally]: https://biomejs.dev/guides/manual-installation/ ## Unsaved files & VS Code settings The extension now supports formatting and linting unsaved (Untitled) files, as well as your VS Code settings. When you open one of these, the extension will spin up a global Biome instance on demand. As with single-file mode, this feature requires [Biome to be installed globally]. The extension will notify you if it’s missing from your PATH. [Biome to be installed globally]: https://biomejs.dev/guides/manual-installation/ ## Automatic reload When the extension detects that Biome has been updated in your project dependencies, it will automatically reload the relevant Biome instances to use the latest version. Additionally, any changes to the extension’s configuration will trigger a reload of the Biome instance to ensure your new settings take effect immediately. ## Improved status indicator The status bar now more reliably reflects the status of Biome for your active workspace folder. When you switch between workspace folders, the indicator updates accordingly. Plus, clicking the status indicator opens the logs for the current Biome instance, making it easier to access logs when troubleshooting. ## Retiring the downloader From the start, the downloader was meant to bridge the gap until you installed Biome as a project dependency. Managing the lifecycle of downloaded binaries—including updates and cross-platform support is complex. We believe package managers handle this better than we could. Going forward, if the extension needs a global Biome installation but can’t find it, you’ll see a notification with instructions on how to install Biome globally. And don’t worry, you can easily silence this notification if you prefer not to be reminded. --- --- title: Biome v1.5 excerpt: | This version has few features around the CLI and many fixes in our formatter. The TypeScript, JSX and JavaScript formatter has surpassed the 97% compatibility rate with Prettier. Biome now provides over 190 lint rules. authors: - ema - team date: 2024-01-08 cover: light: "@/assets/blog/roadmap-2024/banner-light.png" dark: "@/assets/blog/roadmap-2024/banner-dark.png" alt: The brand of the project. It says "Biome, toolchain of the web" socialImage: "@/assets/social-logo.png" --- Along with the [Roadmap for 2024](/blog/roadmap-2024), the [new logo and homepage](/blog/roadmap-2024#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: ```shell npm install --save-dev --save-exact @biomejs/biome@latest npx @biomejs/biome migrate ``` ## New features - 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 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: ```json title="biome.json" ins={5} { "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: ```shell ins="--changed" biome format --changed --write ``` ### 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 `ci`because, 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.  It's possible that you would need to change your permissions of your workflow files in case you don't see the annotations: ```yaml title=".github/workflows/action.yml" permissions: pull-requests: write ``` ### A new command `biome explain` 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`: ```shell biome explain noAccumulatingSpread ``` Which will print the following Markdown: ``````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` 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`: ```json title="biome.json" ins="1.5.0" del={2} ins={3} { "$schema": "https://biomejs.dev/schemas/1.4.1/schema.json" "$schema": "https://biomejs.dev/schemas/1.5.0/schema.json" } ``` ### New rules #### [useExportType](/linter/rules/use-export-type) ```ts 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·};
│ +++++
#### [useImportType](/linter/rules/use-import-type)
```ts
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";
│ +++++
#### [useFilenamingConvention](/linter/rules/use-filenaming-convention)
Enforces naming conventions for JavaScript and TypeScript filenames.
#### [useNodejsImportProtocol](/linter/rules/use-nodejs-import-protocol)
```jsx
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 │
#### [noNodejsModules](/linter/rules/no-nodejs-modules)
```jsx
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.
#### [noInvalidUseBeforeDeclaration](/linter/rules/no-invalid-use-before-declaration)
```jsx
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.
#### [noGlobalEval](/linter/rules/no-global-eval)
```jsx
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().
#### [noGlobalAssign](/linter/rules/no-global-assign)
```jsx
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.
#### [noMisleadingCharacterClass](/linter/rules/no-misleading-character-class)
```jsx
/^[Á]$/u;
```
nursery/noMisleadingCharacterClass.js:1:1 lint/nursery/noMisleadingCharacterClass ━━━━━━━━━━━━━━━━━━
⚠ Unexpected combined character in the character class.
> 1 │ /^[Á]$/u;
│ ^^^^^^^^
2 │
#### [noThenProperty](/linter/rules/no-then-property)
```jsx
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 │
```jsx
const foo = {
get then() {
}
};
```
#### [noUselessTernary](/linter/rules/no-useless-ternary)
```jsx
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.
---
---
title: Biome v1.7
excerpt: |
This new version provides an easy path to migrate from ESLint and Prettier.
It also introduces machine-readable reports for the formatter and the linter, new linter rules, and many fixes.
authors:
- conaclos
- team
date: 2024-04-15
cover:
light: "@/assets/blog/roadmap-2024/banner-light.png"
dark: "@/assets/blog/roadmap-2024/banner-dark.png"
alt: The brand of the project. It says "Biome, toolchain of the web"
socialImage: "@/assets/social-logo.png"
---
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
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:
```json title=".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:
```json title="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:
```json title="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](/linter/rules-sources/) that lists the equivalent Biome rule of a given ESLint rule. We handle some ESLint plugins such as [TypeScript ESLint](https://typescript-eslint.io/), [ESLint JSX A11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y), [ESLint React](https://github.com/jsx-eslint/eslint-plugin-react), and [ESLint Unicorn](https://github.com/sindresorhus/eslint-plugin-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
[Biome v1.6 introduced the subcommand `biome migrate prettier`](/blog/biome-v1-6/#easier-migration-from-prettier).
In Biome v1.7, we add support of [Prettier's
`overrides`](https://prettier.io/docs/en/configuration.html#configuration-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`](/reference/configuration/#overrides). Given the following `.prettierrc.json`
```json title=".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:
```json title="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.
## Emit machine-readable reports
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:
```shell
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.
## Check `git` staged files
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:
```shell
biome check --staged .
```
This is handy for writing your own [pre-commit script](/recipes/git-hooks/#shell-script). Note that unstaged changes on a staged file are
**not** ignored. Thus, we still recommend using a [dedicated pre-commit tool](/recipes/git-hooks/).
Thanks to [@castarco](https://github.com/castarco) for implementing this feature!
## Linter
### New nursery rules
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:
- [nursery/noConstantMathMinMaxClamp](/linter/rules/no-constant-math-min-max-clamp/)
- [nursery/noDoneCallback](/linter/rules/no-done-callback/)
- [nursery/noDuplicateElseIf](/linter/rules/no-duplicate-else-if/)
- [nursery/noEvolvingTypes](/linter/rules/no-evolving-types/)
- [nursery/noFlatMapIdentity](/linter/rules/no-flat-map-identity/)
- [nursery/noMisplacedAssertion](/linter/rules/no-misplaced-assertion/)
### Promoted rules
Once stable, a nursery rule is promoted to a stable group. The following rules are promoted:
- [complexity/noExcessiveNestedTestSuites](/linter/rules/no-excessive-nested-test-suites)
- [complexity/noUselessTernary](/linter/rules/no-useless-ternary/)
- [correctness/useJsxKeyInIterable](/linter/rules/use-jsx-key-in-iterable/)
- [performance/noBarrelFile](/linter/rules/no-barrel-file/)
- [performance/noReExportAll](/linter/rules/no-re-export-all/)
- [style/noNamespaceImport](/linter/rules/no-namespace-import/)
- [style/useNodeAssertStrict](/linter/rules/use-node-assert-strict/)
- [suspicious/noDuplicateTestHooks](/linter/rules/no-duplicate-test-hooks/)
- [suspicious/noExportsInTest](/linter/rules/no-exports-in-test/)
- [suspicious/noFocusedTests](/linter/rules/no-focused-tests/)
- [suspicious/noSkippedTests](/linter/rules/no-skipped-tests/)
- [suspicious/noSuspiciousSemicolonInJsx](/linter/rules/no-suspicious-semicolon-in-jsx)
## Miscellaneous
- 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/`.
```shell
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:
```shell
biome format --config-path=./config/biome.json ./src
```
- You can now ignore
`React` imports in the rules [noUnusedImports](/linter/rules/no-unused-imports/#options) and [useImportType](/linter/rules/use-import-type/#options) by setting [
`javascript.jsxRuntime`](/reference/configuration/#javascriptjsxruntime) to `reactClassic`.
- Biome applies specific settings to [well-known files](/guides/configure-biome/#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](/linter/rules/use-exhaustive-dependencies/) now supports Preact.
See the [changelog](/internals/changelog/#170-2024-04-15) for more details.
## What’s Next?
We have started work on the CSS formatter and linter. Early implementation towards a [plugin system](https://github.com/biomejs/biome/discussions/2286) is also underway. Some of our contributors have started preliminary work for [
_GraphQL_](https://github.com/biomejs/biome/issues/1927) and [YAML](https://github.com/biomejs/biome/issues/2365). Any help is welcome!
If Biome is valuable to you or your company, consider donating monthly to our [Open Collective](https://opencollective.com/biome). You can also [sponsor us on GitHub](https://github.com/sponsors/biomejs). This is important for the sustainability of the project.
Follow us on [our BlueSky](https://bsky.app/profile/biomejs.dev) and join [our Discord community](https://biomejs.dev/chat).
---
---
title: Biome v1.9 Anniversary Release
excerpt: |
Let's celebrate the first anniversary of Biome and the release of Biome v1.9.
This new version enables CSS and GraphQL formatting and linting by default.
It also brings .editorconfig support and introduces a new search command.
authors:
- conaclos
- team
date: 2024-09-12
cover:
light: "@/assets/blog/roadmap-2024/banner-light.png"
dark: "@/assets/blog/roadmap-2024/banner-dark.png"
alt: The brand of the project. It says "Biome, toolchain of the web"
socialImage: "@/assets/social-logo.png"
---
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.
## One year of Biome
We officially [announced Biome](/blog/annoucing-biome/) on 29 August 2023. From its inception, Biome has been a free open source software driven by its community. We have a [governance](https://github.com/biomejs/biome/blob/main/GOVERNANCE.md) and a solid base of contributors to ensure the longevity of the project.
In October 2023, one of the creators of [Prettier](https://prettier.io/) launched [the Prettier challenge](https://console.algora.io/challenges/prettier) 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](/blog/biome-wins-prettier-challenge/) 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](https://eslint.org/)!
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](https://ant.design/), [Astro](https://astro.build/), [Sentry](https://sentry.io/), [daisyUI](https://daisyui.com/), [Refine](https://refine.dev/), [Discord](https://discord.com/), [Pulumi](https://www.pulumi.com/), [Label Studio](https://labelstud.io/), [Spicetify](https://spicetify.app/), [Apify](https://apify.com/), [Slint](https://slint.dev/), [Rspack](https://rspack.dev/), [FluidFramework](https://fluidframework.com/), [and others](https://sourcegraph.com/search?q=file:biome.json&patternType=literal&sm=0). Biome surpassed 2.7 million monthly NPM downloads in August 2024.

We gained sponsorship, notably [Shiguredo](https://shiguredo.jp/), [l2BEAT](https://l2beat.com/), [Phoenix Labs](https://www.phoenixlabs.dev/), [KANAME](https://kanamekey.com/), [Nanabit](https://nanabit.dev/), [Vital](https://vital.io/), [CodeRabbit](https://coderabbit.ai/), and [Forge42](https://forge42.dev/). 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](https://opencollective.com/biome)!
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](https://github.com/biomejs/biome/blob/main/CONTRIBUTING.md#current-members).
In June 2024, Biome won the [JSNation's productivity booster Open Source Award](https://osawards.com/javascript/2024).
## Biome v1.9
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:
```shell
biome migrate --write
```
### 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](https://stylelint.io/):
- [a11y/useGenericFontNames](https://biomejs.dev/linter/rules/use-generic-font-names/)
- [correctness/noInvalidDirectionInLinearGradient](https://biomejs.dev/linter/rules/no-invalid-direction-in-linear-gradient/)
- [correctness/noInvalidGridAreas](https://biomejs.dev/linter/rules/no-invalid-grid-areas/)
- [correctness/noInvalidPositionAtImportRule](https://biomejs.dev/linter/rules/no-invalid-position-at-import-rule/)
- [correctness/noUnknownFunction](https://biomejs.dev/linter/rules/no-unknown-function/)
- [correctness/noUnknownMediaFeatureName](https://biomejs.dev/linter/rules/no-unknown-media-feature-name/)
- [correctness/noUnknownProperty](https://biomejs.dev/linter/rules/no-unknown-property/)
- [correctness/noUnknownUnit](https://biomejs.dev/linter/rules/no-unknown-unit/)
- [correctness/noUnmatchableAnbSelector](https://biomejs.dev/linter/rules/no-unmatchable-anb-selector/)
- [suspicious/noDuplicateAtImportRules](https://biomejs.dev/linter/rules/no-duplicate-at-import-rules/)
- [suspicious/noDuplicateFontNames](https://biomejs.dev/linter/rules/no-duplicate-font-names/)
- [suspicious/noDuplicateSelectorsKeyframeBlock](https://biomejs.dev/linter/rules/no-duplicate-selectors-keyframe-block/)
- [suspicious/noEmptyBlock](https://biomejs.dev/linter/rules/no-empty-block/)
- [suspicious/noImportantInKeyframe](https://biomejs.dev/linter/rules/no-important-in-keyframe/)
- [suspicious/noShorthandPropertyOverrides](https://biomejs.dev/linter/rules/no-shorthand-property-overrides/)
It also provides the following nursery lint rules:
- [nursery/noDuplicateCustomProperties](https://biomejs.dev/linter/rules/no-duplicate-custom-properties/)
- [nursery/noIrregularWhitespace](https://biomejs.dev/linter/rules/no-irregular-whitespace/)
- [nursery/noUnknownPseudoClass](https://biomejs.dev/linter/rules/no-unknown-pseudo-class/)
- [nursery/noUnknownPseudoElement](https://biomejs.dev/linter/rules/no-unknown-pseudo-element/)
- [nursery/noValueAtRule](https://biomejs.dev/linter/rules/no-value-at-rule/)
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:
```json
{
"css": {
"formatter": {
"enabled": false
},
"linter": {
"enabled": false
}
}
}
```
or on the command line:
```shell
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](https://github.com/denbezrukov), [Jon Egeland @faultyserver](https://github.com/faultyserver) and [Yoshiaki Togami @togami2864](https://github.com/togami2864) for coordinating and implementing most of the features related to CSS.
### Stable GraphQL formatter and linter
Another brand new feature: Biome now formats and lints [GraphQL](https://graphql.org/) files by default.
For now, Biome provides only two nursery lint rules:
- [nursery/noDuplicateFields](https://biomejs.dev/linter/rules/no-duplicate-fields/)
- [nursery/useDeprecatedReason](https://biomejs.dev/linter/rules/use-deprecated-reason/)
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:
```json
{
"graphql": {
"formatter": {
"enabled": false
},
"linter": {
"enabled": false
}
}
}
```
or on the command line:
```shell
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](https://www.swan.io/) that funded the implementation of the GraphQL formatter and to [Võ Hoàng Long @vohoanglong0107](https://github.com/vohoanglong0107) for implementing most of the features related to GraphQL.
### Search command
Back in February, one of our Core Contributors published [a proposal for plugin support](https://github.com/biomejs/biome/discussions/1762). One of the highlights was the use of GritQL as a foundation for our plugin system.
[GritQL](https://docs.grit.io/language/overview) 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](https://github.com/biomejs/biome/discussions/2286) [status](https://github.com/biomejs/biome/discussions/2585) [updates](https://github.com/biomejs/biome/discussions/3392). 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](https://github.com/biomejs/biome/issues/2582).
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:
```shell
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](https://grit.io) for open-sourcing GritQL, [Arend van Beelen @arendjr](https://github.com/arendjr) for integrating the GritQL engine into Biome, and to [@BackupMiles](https://github.com/BackupMiles/) for implementing the formatting of search results in the `biome search` command!
### `.editorconfig` support
Biome is now able to take the [`.editorconfig`](https://editorconfig.org/) of your project into account. This is an opt-in feature. You have to turn it on in your Biome configuration file:
```json title="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](https://github.com/dyc3) for implementing this feature!
### JavaScript formatter and linter
We updated the JavaScript formatter to match [Prettier v3.3](https://github.com/prettier/prettier/blob/main/CHANGELOG.md#333). The most significant change is adding parentheses around nullish coalescing in ternaries. This change adds clarity to operator precedence.
```js
// 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:
- [a11y/noLabelWithoutControl](https://biomejs.dev/linter/rules/no-label-without-control/)
- [a11y/useFocusableInteractive](https://biomejs.dev/linter/rules/use-focusable-interactive/)
- [accessibility/useSemanticElements](https://biomejs.dev/linter/rules/use-semantic-elements/)
- [complexity/noUselessStringConcat](https://biomejs.dev/linter/rules/no-useless-string-concat/)
- [complexity/noUselessUndefinedInitialization](https://biomejs.dev/linter/rules/no-useless-undefined-initialization/)
- [complexity/useDateNow](https://biomejs.dev/linter/rules/use-date-now/)
- [correctness/noUndeclaredDependencies](https://biomejs.dev/linter/rules/no-undeclared-dependencies/)
- [correctness/noInvalidBuiltinInstantiation](https://biomejs.dev/linter/rules/no-invalid-builtin-instantiation/)
- [correctness/noUnusedFunctionParameters](https://biomejs.dev/linter/rules/no-unused-function-parameters/)
- [correctness/useImportExtensions](https://biomejs.dev/linter/rules/use-import-extensions/)
- [performance/useTopLevelRegex](https://biomejs.dev/linter/rules/use-top-level-regex/)
- [style/noDoneCallback](https://biomejs.dev/linter/rules/no-done-callback/)
- [style/noYodaExpression](https://biomejs.dev/linter/rules/no-yoda-expression/)
- [style/useConsistentBuiltinInstantiation](https://biomejs.dev/linter/rules/use-consistent-builtin-instantiation/)
- [style/useDefaultSwitchClause](https://biomejs.dev/linter/rules/use-default-switch-clause/)
- [style/useExplicitLengthCheck](https://biomejs.dev/linter/rules/use-explicit-length-check/)
- [style/useThrowNewError](https://biomejs.dev/linter/rules/use-throw-new-error/)
- [style/useThrowOnlyError](https://biomejs.dev/linter/rules/use-throw-only-error/)
- [suspicious/noConsole](https://biomejs.dev/linter/rules/no-console/)
- [suspicious/noEvolvingTypes](https://biomejs.dev/linter/rules/no-evolving-types/)
- [suspicious/noMisplacedAssertion](https://biomejs.dev/linter/rules/no-misplaced-assertion/)
- [suspicious/noReactSpecificProps](https://biomejs.dev/linter/rules/no-react-specific-props/)
- [suspicious/useErrorMessage](https://biomejs.dev/linter/rules/use-error-message/)
- [suspicious/useNumberToFixedDigitsArgument](https://biomejs.dev/linter/rules/use-number-to-fixed-digits-argument/)
We added the following new rules:
- [nursery/noCommonJs](https://biomejs.dev/linter/rules/no-common-js/)
- [nursery/noDuplicateCustomProperties](https://biomejs.dev/linter/rules/no-duplicate-custom-properties/)
- [nursery/noDynamicNamespaceImportAccess](https://biomejs.dev/linter/rules/no-dynamic-namespace-import-access/)
- [nursery/noEnum](https://biomejs.dev/linter/rules/no-enum/)
- [nursery/noIrregularWhitespace](https://biomejs.dev/linter/rules/no-irregular-whitespace)
- [nursery/noRestrictedTypes](https://biomejs.dev/linter/rules/no-restricted-types/)
- [nursery/noSecrets](https://biomejs.dev/linter/rules/no-secrets/)
- [nursery/noUselessEscapeInRegex](https://biomejs.dev/linter/rules/no-useless-escape-in-regex/)
- [nursery/useConsistentMemberAccessibility](https://biomejs.dev/linter/rules/use-consistent-member-accessibility/)
- [nursery/useTrimStartEnd](https://biomejs.dev/linter/rules/use-trim-start-end/)
And we deprecated the following rules:
- `correctness/noInvalidNewBuiltin`. Use [correctness/noInvalidBuiltinInstantiation](https://biomejs.dev/linter/rules/no-invalid-builtin-instantiation/) instead.
- `style/useSingleCaseStatement`. Use [correctness/noSwitchDeclarations](https://biomejs.dev/linter/rules/no-switch-declarations/) instead.
- `suspicious/noConsoleLog`. Use [suspicious/noConsole](https://biomejs.dev/linter/rules/no-console/) instead.
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.
### And more!
For the full list of changes, please refer to our [changelog](/internals/changelog/).
## What's next
### VSCode plugin v3
[Nicolas Hedger @nhedger](https://github.com/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.
### Biome 2.0
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](https://biomejs.dev/internals/versioning/), 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.
---
---
title: Biome v2.0 beta
excerpt: |
Biome 2.0 will be packed with major features and many smaller fixes, rules, and other improvements.
There's a lot to unpack, and we request the community's help testing this beta, so the final
release can be as smooth as possible.
authors:
- arendjr
- dyc3
- team
date: 2025-03-24
cover:
light: "@/assets/blog/roadmap-2024/banner-light.png"
dark: "@/assets/blog/roadmap-2024/banner-dark.png"
alt: The brand of the project. It says "Biome, toolchain of the web"
socialImage: "@/assets/social-logo.png"
---
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:
```shell
npm install --save-dev --save-exact @biomejs/biome@beta
npx @biomejs/biome@beta migrate --write
```
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/.
## New features
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.
### Plugins
Biome 2.0 comes with our first iteration of [Linter Plugins](/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()`:
```grit
`$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.
### Domains
We've introduced a new linter feature: [Domains](https://next.biomejs.dev/linter/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:
```json5
// 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.
### Multi-file analysis
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](https://github.com/biomejs/biome/issues/new?template=03_bug.yml).
For now, we have a few interesting rules that can make use of our multi-file analysis:
- [`noImportCycles`](https://next.biomejs.dev/linter/rules/no-import-cycles/) is able to look at import statements and detect cycles between them.
- [`noPrivateImports`](https://next.biomejs.dev/linter/rules/no-private-imports/) is a new rule based on the `useImportRestrictions` nursery rule from Biome 1.x, and inspired by ESLint's [`plugin-import-access`](https://github.com/uhyo/eslint-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`](https://next.biomejs.dev/linter/rules/use-import-extensions/) has been improved because it can now determine the actual extension that needs to be used for an import, instead of guessing based on heuristics.
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.
### `noFloatingPromises`
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`](https://next.biomejs.dev/linter/rules/no-floating-promises) 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:
```js title="example.js"
async function returnsPromise() { /* ... */ }
returnsPromise().then(() => {});
```
It will trigger the following diagnostic:
```text showLineNumbers=false
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!
### Import Organizer Revamp
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:
```js title="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:
```js title="organizer_v1.js"
import { lib2 } from "library2";
import { lib1 } from "library1";
import { util } from "./utils.js";
```
But instead, what we really wanted was this:
```js title="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:
```js title="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:
```js title="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:
```js title="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/.
### Assists
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`](https://next.biomejs.dev/assist/actions/use-sorted-keys/) can sort keys in object literals, while [`useSortedAttributes`](https://next.biomejs.dev/assist/actions/use-sorted-attributes/) can sort attributes in JSX.
For more information about assists, see: https://next.biomejs.dev/assist/
### Improved suppressions
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
### HTML formatter
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](https://github.com/biomejs/biome/issues)!
You can enable the HTML formatter by adding the following to your config file:
```json
{
"html": {
"formatter": {
"enabled": true
}
}
}
```
### New rules
Several new rules have added since v1.9:
- [`noAwaitInLoop`](https://next.biomejs.dev/linter/rules/no-await-in-loop)
- [`noBitwiseOperators`](https://next.biomejs.dev/linter/rules/no-bitwise-operators/)
- [`noDestructuredProps`](https://next.biomejs.dev/linter/rules/no-destructured-props/)
- [`noFloatingPromises`](https://next.biomejs.dev/linter/rules/no-floating-promises)
- [`noImportCycles`](https://next.biomejs.dev/linter/rules/no-import-cycles)
- [`noPrivateImports`](https://next.biomejs.dev/linter/rules/no-private-imports/)
- [`noTsIgnore`](https://next.biomejs.dev/linter/rules/no-ts-ignore)
- [`noUnwantedPolyfillio`](https://next.biomejs.dev/linter/rules/no-unwanted-polyfillio)
- [`useConsistentObjectDefinition`](https://next.biomejs.dev/linter/rules/use-consistent-object-definition/)
- [`useForComponent`](https://next.biomejs.dev/linter/rules/use-for-component/)
### Miscellaneous
- **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`](https://biomejs.dev/linter/rules/no-undeclared-dependencies/) 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.
### And more!
For the full list of changes, please refer to our [changelog](/internals/changelog/).
---
---
title: Biome formatter wins the Prettier challenge
excerpt: Biome formatter now 95% compatible with Prettier
authors:
- ema
- team
date: 2023-11-27
cover:
light: "@/assets/blog/prettier-challenge.png"
dark: "@/assets/blog/prettier-challenge.png"
alt: The Prettier challenge banner, with the Biome logo over it
socialImage: "@/assets/blog/prettier-challenge.png"
---
With the release of Biome **`v1.4.0`
**, we claim the bounty of the [Prettier challenge](https://console.algora.io/challenges/prettier)!
With
`v1.4.0`, you'll get a better formatter experience, more formatting options, new VSCode features, new sponsors and more!
You can upgrade Biome by running the following command:
```bash
npm install --save-dev --save-exact @biomejs/biome@1.4.0
pnpm update --save-exact @biomejs/biome@1.4.0
yarn upgrade --exact @biomejs/biome@1.4.0
```
## Better formatter
Biome formatter has now **over 96% in terms of compatibility
** against [Prettier](https://prettier.io/)! This score is computed for JavaScript, TypeScript, and JSX formatting.
Merit of challenge that was launched by [Christopher Chedeau](http://blog.vjeux.com/), one of the Prettier's creators.
The challenge attracted the attention of many people, and some of them decided to contribute to Biome to claim part of the bounty. I did see something amazing: contributors had an amazing coordination, they took ownership of the tasks and delivered the solution in a matter of hours.
I believe the main factors that made this possible are three:
1. Money. It's a fact, and it's completely fine if someone decides to contribute only for earning a small stipend out of it.
2. Communication. We used [GitHub](https://github.com/biomejs/biome/issues/720) as only medium of coordination. We provided information, instructions and help on how to deliver.
3. Infrastructure. Biome relies on a solid testing infrastructure, built by [previous](https://github.com/MichaReiser) Rome Tools [employees](https://github.com/ematipico) and [contributors](https://github.com/IWANABETHATGUY/). It's able to catch every reformat bug, provide granular diffs and warn the user if the emitted output is the different from the one emitted by Prettier.
Before the challenge, Biome had roughly a compatibility rate of 85%, based on our internal metrics (JavaScript, TypeScript and JSX, on options parity). Even though 85% might seem high, the impact of a low number such as 15% on big code bases is huge, and people might feel intimidated by so many changes, causing early adopters to receive frictions when bring Biome to their team. A member of our community shared some insights:
> As a great example of how much even just that last 5% has improved things for large codebases (and specifically with
`bracketSpacing` and now `bracketSameLine` implemented) i ran it one project in our monorepo [...].
>
> Just last week, this number
`[diagnostics]` was more than 6,000. Even with the bracket options ignored, it was still more than 1000, and now there are only 200 left!
Although the challenge is over, we are committed to improve even more the compatibility score with prettier. Any contribution in this regard is very welcome.
The challenge has also uncovered some cases in Prettier's emitted output that we decided to not follow. We have created a [new section](/formatter/differences-with-prettier) in our website that explains them. Our hope is to make this section smaller with the time.
If there's a divergence that isn't documented in our website, you should consider that a bug and file an issue.
#### New formatting options
With this challenge, we added new options to the formatter:
- [`lineEnding`](/reference/configuration#formatterlineending)
Use this option to match the line endings of your OS. We support `lf` (line feed - `\n`), `cr` (carriage return -
`\r`) and `crlf` (carriage return line feed - `\r\n`).
- [`bracketSameLine`](/reference/configuration#javascriptormatterbracketsameline)
```jsx title="example.js"
// Existing behavior. Now also the default, meaning `bracketSameLine: false`.
nursery/noDefaultExport.js:1:8 lint/nursery/noDefaultExport ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ Avoid default exports.
> 1 │ export default function f() {};
│ ^^^^^^^
2 │
ℹ Default exports cannot be easily discovered inside an editor and don't encourage the use of consistent names through a code base.
ℹ Use a named export instead.
- [noAriaHiddenOnFocusable](/linter/rules/no-aria-hidden-on-focusable)
```jsx
```
nursery/noAriaHiddenOnFocusable.js:1:1 lint/nursery/noAriaHiddenOnFocusable FIXABLE ━━━━━━━━━━━━━━
✖ Disallow aria-hidden="true" from being set on focusable elements.
> 1 │ <div aria-hidden="true" tabIndex="0" />
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │
ℹ aria-hidden should not be set to true on focusable elements because this can lead to confusing behavior for screen reader users.
ℹ Unsafe fix: Remove the aria-hidden attribute from the element.
1 │ <div·aria-hidden="true"·tabIndex="0"·/>
│ -------------------
- [noImplicitAnyLet](/linter/rules/no-implicit-any-let)
```ts
var a;
a = 2;
```
nursery/noImplicitAnyLet.js:1:5 lint/nursery/noImplicitAnyLet ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ This variable implicitly has the any type.
> 1 │ var a;
│ ^
2 │ a = 2;
3 │
ℹ Variable declarations without type annotation and initialization have implicitly the any type. Declare type or initialize the variable with some value.
- [useAwait](/linter/rules/use-await)
```jsx
async function fetchData() {
// Missing `await` for the promise returned by `fetch`
return fetch("/data");
}
```
nursery/useAwait.js:1:1 lint/nursery/useAwait ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ This async function lacks an await expression.
> 1 │ async function fetchData() {
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 2 │ // Missing `await` for the promise returned by `fetch`
> 3 │ return fetch('/data');
> 4 │ }
│ ^
5 │
ℹ Remove this async modifier, or add an await expression in the function.
> 1 │ async function fetchData() {
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 2 │ // Missing `await` for the promise returned by `fetch`
> 3 │ return fetch('/data');
> 4 │ }
│ ^
5 │
ℹ Async functions without await expressions may not need to be declared async.
- [useValidAriaRole](/linter/rules/use-valid-aria-role)
```jsx
```
nursery/useValidAriaRole.js:1:1 lint/nursery/useValidAriaRole FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Enforce that elements with ARIA roles must use a valid, non-abstract ARIA role.
> 1 │ <div role="datepicker"></div>
│ ^^^^^^^^^^^^^^^^^^^^^^^
2 │
ℹ Check WAI-ARIA for valid roles or provide options accordingly.
ℹ Unsafe fix: Remove the invalid role attribute.
Check the list of all valid role attributes.
1 │ <div·role="datepicker"></div>
│ -----------------
- [useRegexLiterals](/linter/rules/use-regex-literals)
```jsx
new RegExp("abc", "u");
```
nursery/useRegexLiterals.js:1:1 lint/nursery/useRegexLiterals FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠ Use a regular expression literal instead of the RegExp constructor.
> 1 │ new RegExp("abc", "u");
│ ^^^^^^^^^^^^^^^^^^^^^^
2 │
ℹ Regular expression literals avoid some escaping required in a string literal, and are easier to analyze statically.
ℹ Safe fix: Use a literal notation instead.
1 │ - new·RegExp("abc",·"u");
1 │ + /abc/u;
2 2 │
### Recommended rules
- [a11y/noAccessKey](/linter/rules/no-access-key)
```jsx
```
a11y/noAccessKey.js:1:22 lint/a11y/noAccessKey FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Avoid the accessKey attribute to reduce inconsistencies between keyboard shortcuts and screen reader keyboard comments.
> 1 │ <input type="submit" accessKey="s" value="Submit" />
│ ^^^^^^^^^^^^^
2 │
ℹ Assigning keyboard shortcuts using the accessKey attribute leads to inconsistent keyboard actions across applications.
ℹ Unsafe fix: Remove the accessKey attribute.
1 │ <input·type="submit"·accessKey="s"·value="Submit"·/>
│ --------------
- [a11y/useHeadingContent](/linter/rules/use-heading-content)
```jsx
```
a11y/useHeadingContent.js:1:1 lint/a11y/useHeadingContent ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Provide screen reader accessible content when using heading elements.
> 1 │ <h1 />
│ ^^^^^^
2 │
ℹ All headings on a page should have content that is accessible to screen readers.
- [complexity/useSimpleNumberKeys](/linter/rules/use-simple-number-keys)
```jsx
({ 0x1: 1 });
```
complexity/useSimpleNumberKeys.js:1:4 lint/complexity/useSimpleNumberKeys FIXABLE ━━━━━━━━━━━━━━━━
✖ Hexadecimal number literal is not allowed here.
> 1 │ ({ 0x1: 1 });
│ ^^^
2 │
ℹ Safe fix: Replace 0x1 with 1
1 │ - ({·0x1:·1·});
1 │ + ({·1:·1·});
2 2 │
### Promoted rules
- [a11y/noInteractiveElementToNoninteractiveRole](/linter/rules/no-interactive-element-to-noninteractive-role)
- [complexity/noThisInStatic](/linter/rules/no-this-in-static)
- [complexity/useArrowFunction](/linter/rules/use-arrow-function)
- [correctness/noEmptyCharacterClassInRegex](/linter/rules/no-empty-character-class-in-regex)
- [correctness/noInvalidNewBuiltin](/linter/rules/no-invalid-new-builtin)
- [style/noUselessElse](/linter/rules/no-useless-else)
- [style/useAsConstAssertion](/linter/rules/use-as-const-assertion)
- [style/useShorthandAssign](/linter/rules/use-shorthand-assign)
- [suspicious/noApproximativeNumericConstant](/linter/rules/no-approximative-numeric-constant)
- [suspicious/noMisleadingInstantiator](/linter/rules/no-misleading-instantiator)
- [suspicious/noMisrefactoredShorthandAssign](/linter/rules/no-misrefactored-shorthand-assign)
### Deprecated rules
- [correctness/noNewSymbol](/linter/rules/no-new-symbol)
The rule is replaced by [correctness/noInvalidNewBuiltin](/linter/rules/no-invalid-new-builtin)
## Homage to our maintainers
Since Biome was forked, new people joined the project. They have been helping with in so many ways that you can't even imagine: new features, side projects, engaging with the community, support, documentation, and more. OSS is not just about coding.
Thank you to:
- [Madeline Gurriarán @SuperchupuDev](https://github.com/SuperchupuDev)
- [Nicolas Hedger @nhedger](https://github.com/nhedger)
- [Victor Teles @victor-teles](https://github.com/victor-teles)
And a big welcome to our new joined maintainer:
- [Jon Egeland @faultyserver](https://github.com/faultyserver)
- [Takayuki Maeda @TaKO8Ki](https://github.com/TaKO8Ki)
## New sponsors
Last but not least, we are proud to announce that we have two new sponsors:
- Gold: Shiguredō (https://shiguredo.jp/)
- Bronze: KANAME (https://www.kanamekey.com/)
If you want to economically contribute to the project and help it to ship more features, you can do so from the [GitHub Sponsorship page](https://github.com/sponsors/biomejs/) or the [Open Collective page](https://opencollective.com/biome).
## What's next
The project is thriving, with more people curious about the project and contributors that want to be involved.
In the next months we will focus on:
- Publishing a Roadmap. **Keep an eye on it**, it will involve a lot of **interesting** work.
- Rebranding the website with a new logo.
- Translate the website in Japanese.
## Translations
- [中文翻译: Biome赢得了Prettier挑战](https://juejin.cn/post/7308643782375768118)
---
---
title: Roadmap 2024
excerpt: Roadmap 2024, new logo and homepage
authors:
- ema
- team
date: 2024-01-08
cover:
light: "@/assets/blog/roadmap-2024/banner-light.png"
dark: "@/assets/blog/roadmap-2024/banner-dark.png"
alt: The Prettier challenge banner, with the Biome logo over it
socialImage: "@/assets/social-logo.png"
---
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:
- [**Be involved in the project and the community**](https://github.com/biomejs). Please help us to build those features.
- [**Sponsor us**](https://opencollective.com/biome). Ask your company to sponsor us. Biome is so fast that it can reduce your company's CI times and save money. Performance is part of our mission. Plus, sponsorship is a good medium of
_advertisement_ for your company.
- [**Improve our documentation with ideas, recipes, or guides**](/guides/getting-started). Translate our documentation and help us to make Biome available to people who aren't proficient in English.
## Preface
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](/internals/philosophy/) and provide the best experience by default.
## Main area of focus
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
## Help users to move to Biome
- 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
CSS is our next language of focus, and we are making good progress. HTML and Markdown will follow. Follow our [up-to-date page](/internals/language-support) 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](https://vuejs.org/), [Svelte](https://svelte.dev/) and [Astro](https://astro.build/), and this would require some exploration of how to represent super languages of HTML.
## Deepen Biome's existing capabilities to offer more functionalities.
- Project analysis and dependency resolution
- Type system
- CLI
### 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
### Type system
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.
### CLI
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;
## Plugins
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
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.
## Community and content
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](https://github.com/biomejs/biome/blob/main/GOVERNANCE.md#maintainer-nomination).
Recently Biome started its own [YouTube Channel](https://www.youtube.com/channel/UC6ssscaFgCSlbv1Pb6krGVw). We will use this channel to share learning content with the community.
## New logo and homepage
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.
---
---
title: Roadmap 2025 and Biome 2.0
excerpt: "A look at what 2025 will bring for us: Biome 2.0, enterprise support, and our roadmap"
authors:
- arendjr
- team
date: 2025-01-22
cover:
light: "@/assets/blog/roadmap-2024/banner-light.png"
dark: "@/assets/blog/roadmap-2024/banner-dark.png"
alt: "Biome - Toolchain of the web"
socialImage: "@/assets/social-logo.png"
featured: true
---
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.
## 🎆 Recap: Biome 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](https://biomejs.dev/reference/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`](https://biomejs.dev/linter/rules/use-sorted-classes/) that marks the beginning of dedicated **Tailwind** support.
* Our [team of maintainers](https://github.com/biomejs/biome/blob/main/CONTRIBUTING.md#current-members) has grown from 10 members at the start of 2024 to 18 today.
* We won the **Productivity Booster** award of the [OS Awards 2024](https://osawards.com/javascript/2024).
* We gained several new [sponsors](https://github.com/biomejs/biome#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.
## 💳 Enterprise Support
One more thing that we are happy to announce is that as of January 2025, we are also offering [Enterprise Support](https://biomejs.dev/enterprise) for Biome. Hopefully this will allow some of our contributors to spend more of their time and effort towards Biome!
## ⏭️ Biome 2.0
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](https://github.com/biomejs/biome/discussions/1762) 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](https://docs.grit.io/language/overview).
* **Domains**. [Domains](https://github.com/biomejs/biome/blob/main/.changeset/introduce_the_domains_linter_feature.md) 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](https://github.com/biomejs/biome/issues/3307) 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.
## 🌌 2025 roadmap
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**](https://github.com/biomejs/biome/issues/4726). No toolchain for the web is complete without it, and we're already working on it!
* [**Embedded languages**](https://github.com/biomejs/biome/issues/3334). 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**](https://github.com/biomejs/biome/issues/3187). 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](https://github.com/biomejs/biome/pull/4911) 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](https://www.typescriptlang.org/tsconfig/#isolatedModules).
* **JSDoc support**. Can we use [JSDoc](https://jsdoc.app/) 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](https://github.com/biomejs/biome/issues/3718) 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.
## ❤️ Your Support
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](https://github.com/biomejs/biome/blob/main/CONTRIBUTING.md). Please help us to build those features!
* [Sponsor us](https://github.com/biomejs/biome/tree/main#funding). 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](https://biomejs.dev/enterprise/). 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](https://github.com/biomejs/website/). Write guides or recipes, or help to keep our translations up-to-date for non-English speakers.
---
---
title: Biome partners with Vercel to improve type inference
excerpt: Vercel has become a Platinum Sponsor of Biome to further our type inference efforts
authors:
- arendjr
date: 2025-04-02
cover:
light: "@/assets/blog/roadmap-2024/banner-light.png"
dark: "@/assets/blog/roadmap-2024/banner-dark.png"
alt: The brand of the project. It says "Biome, toolchain of the web"
socialImage: "@/assets/social-logo.png"
featured: true
---
Back at the start of 2024, Biome added an ambitious goal to its
[roadmap](/blog/roadmap-2024): integrate a subset of the
**TypeScript type system** directly into Biome so that type-informed lint rules
can work out of the box.
In order to make this feasible, we first needed better infrastructure. The main
blocker for this was multi-file analysis, which is coming with
[Biome 2.0](/blog/biome-v2-0-beta).
Today, we finally have the technical means to implement this goal, but, as a
project, we need more than only technical means. Which is why we are grateful
to announce Vercel as a partner to help us achieve this goal and push the web
forward.
### Vercel becomes Biome's first platinum sponsor
[Vercel](https://vercel.com/) has contracted me (one of the Biome lead
developers) to work on our type inference effort for many months. Vercel’s goal
with this partnership is to both help improve their own internal linter DX (as
they have recently standardized on Biome) and share those improvements with the
rest of the JavaScript ecosystem.
We aim to have a fully
functioning[(*)](#how-can-you-write-a-type-informed-lint-rule-if-you-dont-know-the-type-information-is-correct)
versions of the [`noFloatingPromises`](https://next.biomejs.dev/linter/rules/no-floating-promises/)
rule and a similar `noMisusedPromises` rule.
## Frequently Asked Questions
Because type inference and type checkers are popular topics in our community,
I have collected a few common questions on this topic.
### Are you reimplementing a type checker in Biome?
No. TypeScript's `tsc` is a complex and fully-featured type checker, and we have
no intention to rebuild it. For type _checking_ you are expected to continue to
use `tsc`.
This work focuses on type _inference_ which is a small subset of the
functionality of a full type checker. The goal is to be able to write lint rules
that act on type information, without needing to prove that this type
information is correct.
### How can you write a type-informed lint rule if you don't know the type information is correct?
Linters have different aims than type checkers. Where a type checker aims to
detect misuse of types, a linter aims to detect common mistakes in general. But
the goal of detecting common mistakes doesn't require 100% correctness when it
comes to the types it operates on. In fact, even the
[TypeScript Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals)
state they are willing to compromise correctness in favor of productivity.
For a linter, what's most important is that we don't flag _false positives_,
instances where our lint rules may think there's an issue when really there's
not. False positives are a source of frustration for developers, because they
take time to analyze; time that was wasted when it turns out there really wasn't
an issue to begin with.
On the other hand, _false negatives_ are less problematic. They represent
situations where we wish the lint rule would flag an issue, but didn't. They can
also represent lost productivity (by not flagging the issue early in the
pipeline), but they are not productivity lost due to the rule itself.
Hypothetically, a lint rule that has no false positives, but has 20% false
negatives, still offers 80% of the value of a rule that is always correct. So
our goal is simply: Create lint rules that don't flag false positives,
while trying to get the amount of false negatives down as much as we can.
We cannot say upfront which percentage we will actually achieve, but since
Vercel is sponsoring this work, we'll use their repositories as a benchmark and
try to optimise towards their use cases.
### How does Microsoft's announcement of a Go port for `tsc` influence your work?
It's too early to tell. The Go port is not available to users yet, and the APIs
that should allow it to be used by other tooling aren't expected until the end
of the year. Additionally, even though the Go port is supposedly much faster
than the Node.js version, it will likely still be significantly slower than an
implementation built into Biome's core due to inter-process communication and
the need to do duplicate work such as parsing files in separate processes.
For now, that gives us an opportunity to pursue our own type inference
implementation and see how it goes. When the Go version is available for
integration into other tools, we can always reevaluate our approach.
### Can we follow your progress?
Yes! There's a public project overview that people can inspect:
https://github.com/orgs/biomejs/projects/4/views/2
Note that issues may be continuously added to the project as false negatives
keep popping up.
---
---
title: Differences with Prettier
description: In-depth explanation of the differences with Prettier.
---
In some cases, Biome has intentionally decided to format code in a way that doesn't match Prettier's output. These divergences are explained below.
## Prettier doesn't unquote some object properties that are valid JavaScript identifiers.
Prettier and Biome unquote object and class properties that are valid JavaScript identifiers.
Prettier [unquotes only valid ES5 identifiers](https://github.com/prettier/prettier/blob/a5d502513e5de4819a41fd90b9be7247146effc7/src/language-js/utils/index.js#L646).
This is a legacy restriction in an ecosystem where ES2015 is now widespread.
Thus, we decided to diverge here by un-quoting all valid JavaScript identifiers in ES2015+.
A possible workaround would be to introduce a configuration to set the ECMAScript version a project uses.
We could then adjust the un-quoting behaviour based on that version.
Setting the ECMAScript version to `ES5` could match Prettier's behaviour.
```js title="example.js"
const obj = {
'a': true,
b: true,
"𐊧": true,
}
```
Diff
```js title="example.js" del={4} ins={5}
const obj = {
a: true,
b: true,
"𐊧": true,
𐊧: true,
};
```
## Prettier has an inconsistent behavior for assignment in computed keys.
Prettier and Biome enclose some assignment expressions between parentheses, particularly in conditionals.
This allows Biome to identify an expression that should be a comparison.
Prettier has inconsistent behaviour because it adds parentheses for an assignment in a computed key of an object property and doesn't for a computed key of a class property, as demonstrated by the following example:
Input
```js title="example.js"
a = {
[x = 0]: 1,
}
class C {
[x = 0] = 1
}
```
Diff
```js title="example.js" del={2} ins={3}
a = {
[(x = 0)]: 1,
[x = 0]: 1,
};
class C {
[x = 0] = 1;
}
```
[Playground link](/playground?enabledLinting=false&code=YQAgAD0AIAB7AAoAIAAgAFsAeAAgAD0AIAAwAF0AOgAgADEALAAKAH0ACgAKAGMAbABhAHMAcwAgAEMAIAB7AAoAIAAgACAAIABbAHgAIAA9ACAAMABdACAAPQAgADEACgB9AAoA)
To be consistent, we decided to diverge and omit the parentheses.
Alternatively, we could enclose any assignment in a computed key of an object or of a class.
## Prettier adds a trailing comma to type parameters of arrow functions even when it is not required.
In some specific cases, a type parameter list of an arrow function requires a trailing comma to distinguish it from a JSX element.
When a default type is provided, this trailing comma is not required.
Here, we diverge from Prettier because we think it better respects the original intent of Prettier, which was to add a trailing comma only when required.
Input
```tsx title="example.tsx"
🐈 😂