Skip to content

Biome v1.5

The Prettier challenge banner, with the Biome logo over itThe Prettier challenge banner, with the Biome logo over it
Emanuele Stoppa & Biome Core Team, Biome Maintainers

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

Update Biome using the following commands:

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

Process only the files that were changed

Section titled Process only the files that were changed

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

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

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

"vcs": {
"enabled": true,
"clientKind": "git",
"defaultBranch": "main"

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

Terminal window
biome format --changed --write

The command biome ci now prints diagnostics in GitHub PRs

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

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

Screenshot of a GitHub annotation printed by Biome

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

pull-requests: write

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

Terminal window
biome explain noAccumulatingSpread

Which will print the following Markdown:

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

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

The command biome migrate updates the $schema

Section titled The command biome migrate updates the $schema

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

"$schema": ""
"$schema": ""
interface I {}
export { I };
nursery/useExportType.js:2:8 lint/nursery/useExportType  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

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

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

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

   Safe fix: Use a grouped export type.

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

   All these imports are only used as types.

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

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

   Safe fix: Use import type.

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

Enforces naming conventions for JavaScript and TypeScript filenames.

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

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

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

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

   Unsafe fix: Change to "node:fs".

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

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

   Using Node.js modules are forbidden.

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

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

   Remove the import module.

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

   Const declarations must have an initialized value.

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

   This variable needs to be initialized.

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

   eval() exposes to security risks and performance issues.

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

   See the MDN web docs for more details.

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

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

   A global variable should not be reassigned.

  > 1 │ Object = null;
    2 │ 

   Assigning to a global variable can override essential functionality.

nursery/noMisleadingCharacterClass.js:1:1 lint/nursery/noMisleadingCharacterClass ━━━━━━━━━━━━━━━━━━

   Unexpected combined character in the character class.

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

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

   Do not add then to an object.

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

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

   Unnecessary use of boolean literals in conditional expression.

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

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

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