# 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. ![Screenshot of a GitHub annotation printed by Biome](../../../assets/blog/roadmap-2024/github-annotation.png) 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. ![Biome monthly NPM downloads](../../../assets/blog/biome-v1-9/biome-monthly-npm-downloads.svg) 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`. Hello ``` After formatting with `"bracketSameLine": true`: ```jsx title="example.js" // New behavior, with `bracketSameLine: true`. Hello ``` - [`bracketSpacing`](/reference/configuration#javascriptformatterbracketspacing) ```js title="example.js" import { sort } from "sort.js"; const value = { sort }; ``` After formatting with `"bracketSpacing": false`: ```js title="example.js" import {sort} from "sort.js"; const value = {sort}; ``` ## VSCode extension goodies The VSCode has been moved to a [new repository](https://github.com/biomejs/biome-vscode). We removed the bundled binary from the extension, and you'll be able to download the version that you want. Here's a small video of how it works: From today, we release a **nightly** version of the extension. This is a version meant for early adopters and to test things before they are officially released. ## Some CLI goodies People that rely on Biome LSP will be pleased that they can now pass a custom configuration to the command `lsp-proxy`, using the option `--config-path`. The same option is accepted by the command `start`: ```shell biome --config-path=../path/where/config/is lsp-proxy biome --config-path=../path/where/config/is start ``` The CLI now exposes the option `--diagnostic-level`, that allows to filter the kind of diagnostics printed to terminal. ```shell biome check --diagnostic-level=error ./src ``` ## New lint rules, and promoted rule Biome is a linter too, and it features [177 rules](/linter/rules/)! In this release, some rules are promoted and new ones are available. ### New rules - [noDefaultExport](/linter/rules/no-default-export) ```jsx export default function f() {} ```
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