Bun v1.4.4

To install Bun

curl

curl -fsSL https://bun.sh/install | bash

npm

npm install -g bun

powershell

powershell -c "irm bun.sh/install.ps1|iex"

scoop

scoop install bun

brew

brew tap oven-sh/bun
brew install bun

docker

docker pull oven/bun
docker run --rm --init --ulimit memlock=-1:-1 oven/bun

To upgrade Bun

bun upgrade

bun fmt: a formatter built into Bun#

bun fmt is an incredibly fast, Prettier-compatible code formatter that works with your existing Prettier or oxfmt config.

bun fmt
src/index.ts
src/styles.css
Formatted 2 files, 2 unchanged [5.59ms]

It formats JavaScript, TypeScript, JSX, Flow, CSS, SCSS, Less, HTML, Vue, Svelte, Angular, Lightning Web Components, MJML, JSON, JSONC, JSON5, YAML, TOML, Markdown, MDX, GraphQL and Handlebars. Embedded code is formatted too, like <style> in HTML, code blocks in Markdown and css`...` templates in JavaScript.

In Prettier's own repository (2,616 files, with their config), bun fmt --check takes 60 ms and Prettier takes 17 seconds:

Tool

Time

Peak memory

bun fmt

59.7 ms

48 MB

Prettier 3.9.10

17.1 s

459 MB

That's 286x faster. On vitest, date-fns, monkeytype and h3, it's 234x to 425x faster than Prettier 3.9.9.

On projects that already use oxfmt, with their own config, it's 3x to 6x faster than oxfmt 0.74.0:

Project

Files

bun fmt

oxfmt 0.74.0

Faster

Memory

RSSHub

7,121

97.3 ms

298.5 ms

3.0x

42 vs 95 MB

redocly-cli

3,397

62.4 ms

217.5 ms

3.4x

61 vs 107 MB

vite

2,537

65.2 ms

406.7 ms

6.2x

64 vs 137 MB

fumadocs

2,452

44.6 ms

1,395 ms

31x

48 vs 179 MB

Both tools see the same files, exit 0 and leave the tree unchanged.

Reproduce these numbers

Each project is a fresh clone at a pinned commit. The oxfmt projects have no node_modules.

vite

bun install -g oxfmt@0.74.0
git clone https://github.com/vitejs/vite && cd vite
git checkout 4ca25e1d3a24
hyperfine --warmup 2 "oxfmt ." "bun fmt ."

redocly-cli

git clone https://github.com/Redocly/redocly-cli && cd redocly-cli
git checkout 82da67d6ea5b
hyperfine --warmup 3 --runs 20 "oxfmt --check ." "bun fmt --check ."

RSSHub

git clone https://github.com/DIYgod/RSSHub && cd RSSHub
git checkout 8776927c78de
hyperfine --warmup 3 --runs 20 "oxfmt --check ." "bun fmt --check ."

fumadocs

git clone https://github.com/fuma-nama/fumadocs && cd fumadocs
git checkout bc86bbb0d406
hyperfine --warmup 3 --runs 20 "oxfmt --check ." "bun fmt --check ."

prettier

git clone https://github.com/prettier/prettier && cd prettier
git checkout df39b5b60a28
bun install --ignore-scripts
hyperfine --warmup 3 "bun fmt --no-script . --check" "node node_modules/prettier/bin/prettier.cjs . --check"

The same runs on one core, and on only vite's JavaScript and TypeScript files ('**/*.{js,mjs,cjs,jsx,ts,mts,cts,tsx}'):

Run

bun fmt

oxfmt 0.74.0

Faster

vite, 1,608 JS and TS files

52.2 ms

188.3 ms

3.6x

RSSHub, one core

621.6 ms

1,212 ms

1.9x

redocly-cli, one core

375.1 ms

645.5 ms

1.7x

fumadocs, one core

255.2 ms

5,608 ms

21x

  • vite: 16-core M4 Max MacBook Pro, macOS 26.7. Mean.

  • Everything else: Intel Xeon Platinum 8488C, 8 physical cores pinned with taskset, Amazon Linux 2023, xfs on NVMe, warm file cache. Median.

bun fmt wouldn't exist without Prettier, Biome and Oxc. It's a port of Prettier, and the JavaScript and TypeScript printer is a port of oxc_formatter, which is a port of Biome's formatter.

Thank you to the Prettier, Biome and Oxc teams for years of great work.

Read more in the docs.

bun fmt --check#

--check lists the files that need formatting without writing anything. It exits with code 1 if there are any.

bun fmt --check
src/index.ts
src/styles.css
2 files need formatting. Run bun fmt to fix them.

bun fmt --staged and --changed#

--staged only formats the files you're about to commit and re-stages them, so you don't need lint-staged.

.git/hooks/pre-commit

#!/bin/sh
bun fmt --staged

--changed formats the files that differ from your default branch. Pass a ref to compare against something else.

bun fmt --changed
bun fmt --changed=origin/dev

Use your Prettier or oxfmt config#

bun fmt reads .prettierrc*, prettier.config.*, "prettier" in package.json, overrides, .editorconfig and .prettierignore. It also reads .oxfmtrc.json, .oxfmtrc.jsonc and oxfmt.config.ts (or .mts). It accepts the same CLI flags as Prettier or oxfmt, and // prettier-ignore comments work.

"scripts": {
"format": "prettier --write ."
"format": "bun fmt"
}

Import sorting is built in, so you can leave @trivago/prettier-plugin-sort-imports, @ianvs/prettier-plugin-sort-imports and prettier-plugin-organize-imports in plugins. Languages that need a Prettier plugin, like Astro, fall back to the Prettier installed in your project.

The command is bun fmt, like cargo fmt, go fmt, deno fmt and zig fmt. bun format still runs your format script.

bun fmt --doctor shows how Bun interprets your config and which packages you can uninstall.

Options in bunfig.toml#

All of Prettier's options are supported under the same names. Each one is also available as a flag, like --print-width 100 or --no-semi. bun fmt --init creates the [fmt] section.

bunfig.toml

[fmt]
printWidth = 100
semi = false
sortImports = true
sortTailwindcss = true
sortPackageJson = true
jsdoc = true

[[fmt.overrides]]
files = ["*.test.ts"]
options = { printWidth = 120 }

sortImports, sortTailwindcss, sortPackageJson and jsdoc are off by default, and don't need a Prettier or oxfmt config. sortImports groups imports, sorts the names in { } and merges duplicate imports from the same module.

In a monorepo, bun fmt walks up from the working directory to the nearest bunfig.toml with a [fmt] section. Without a Prettier config, bun fmt also formats TOML. It skips *.min.js, *.min.css and lockfiles unless you pass them explicitly.

Prettier's Tailwind, package.json and Svelte plugins are built in#

bun fmt does the work of prettier-plugin-tailwindcss, prettier-plugin-packagejson and prettier-plugin-svelte, so you don't need them installed. You can leave them in plugins, and their options are supported.

// Before
<button className="text-white px-4 sm:px-8 py-2 bg-sky-700 hover:bg-sky-800" />
// After
<button className="bg-sky-700 px-4 py-2 text-white hover:bg-sky-800 sm:px-8" />

Tailwind classes are sorted with your project's tailwindcss, version 3 or 4. If it isn't installed, they're left as they are.

We compared the output against Prettier 3.9.9 with version 0.8.1 of the plugin, on Tailwind 4.3.3 and 3.4.19.

Input

Total

Identical

%

JavaScript and TypeScript files

13,952

13,654

97.9%

HTML, Vue, Angular, LWC, Handlebars, CSS, SCSS, Less, Markdown and MDX files

2,176

2,148

98.7%

Tailwind 3 projects

15

15

100%

About half of the differences are intentional. In className={`header${open ? " active" : ""}`}, the plugin trims " active" to "active", so the element ends up with the class headeractive. bun fmt keeps the space.

For package.json, keys are sorted in the same order as the plugin and values are left untouched. Of 13,670 real-world package.json files, 13,644 (99.8%) are byte-for-byte identical to the output of Prettier 3.9.9 with the plugin. 20 differ only in values that Bun preserves, and the plugin throws on the other 6.

.svelte files are formatted by default, and the output matches prettier-plugin-svelte 4.1.1. With a Prettier config, they're formatted if the config lists the plugin. To skip them, set svelte = false in [fmt] or pass --no-svelte.

If your config uses a plugin that bun fmt doesn't support, like prettier-plugin-jsdoc, it prints an error naming the plugin, skips the files the plugin applies to and exits with code 2.

Where bun fmt intentionally differs from Prettier#

Prettier's output changes the meaning of the code for these inputs. bun fmt preserves it.

Input

Prettier 3.9.9

bun fmt

font-family: Font\ Awesome in CSS

Font\Awesome, where \A is a hex escape

Kept

`x

b` in a CSS selector

`x

<!DOCTYPE html> in Handlebars

Dropped

Kept

A <script> with a // comment in Handlebars

Lines joined, so the comment swallows the next line

Kept

bun fmt --debug-check re-parses each file after formatting and fails if the meaning changed, like Prettier's --debug-check.

(节选)

原文:Bun Blog|Bun v1.4.4,2026-10-22

排序方式 :

成为第一条评论!

Nobody's responded to this post yet. Add your thoughts and get the conversation going.