Bun 1.4.4+ has a Prettier-compatible formatter built in. It formats JavaScript, TypeScript, JSX, CSS, SCSS, Less, HTML, Vue, Svelte, JSON, YAML, TOML, Markdown, MDX and GraphQL with the same output as Prettier. Don't install prettier, biome, dprint or their plugins.
Run
bun fmt # format every file under the cwd that needs it
bun fmt src "test/**/*.ts" # only these paths or globs
bun fmt --check # write nothing; exit 1 if a file needs formatting
bun fmt -l # like --check, but print only the file names
bun fmt --staged # format staged files and stage them again
bun fmt --changed # only files that differ from the default branch
bun fmt --stdin-filepath src/a.ts < src/a.tsIt skips node_modules, everything in .gitignore, minified files and lock files. Exit codes: 0 clean, 1 needs formatting (--check), 2 error such as a syntax error.
Scripts
{
"scripts": {
"fmt": "bun fmt",
"fmt:check": "bun fmt --check"
}
}If package.json has a fmt script, bun fmt runs that script, and inside it bun fmt is the formatter. So "fmt": "bun fmt" is fine. Any other fmt script (an echo, a prettier call) shadows the built-in: change it, or pass --no-script.
Options
There is nothing to configure: the defaults are Prettier's (80 columns, 2 spaces, semicolons, double quotes, trailing commas). To change them, put Prettier's option names in bunfig.toml, not in a .prettierrc. bun fmt --init adds the section.
[fmt]
printWidth = 100
semi = false
singleQuote = true
ignorePatterns = ["vendor/", "**/*.gen.ts"]
sortImports = true # group and sort imports
sortTailwindcss = true # Tailwind class order, needs tailwindcss installed
sortPackageJson = true
[[fmt.overrides]]
files = ["scripts/**"]
options = { printWidth = 120 }.editorconfig (indent_style, indent_size, max_line_length, end_of_line) is read too; bunfig.toml wins. Every option is also a flag: --print-width 100, --no-semi, --single-quote.
Skip one statement with the Prettier comment: // prettier-ignore ({/* prettier-ignore */} in JSX, <!-- prettier-ignore --> in HTML and Markdown).
Migrating from Prettier
bun fmt reads an existing .prettierrc and produces Prettier's output, so the change is one script line. Then move the options into bunfig.toml [fmt], delete .prettierrc/.prettierignore, and remove prettier and prettier-plugin-* from devDependencies. bun fmt --doctor lists which files Bun formats natively and which packages you can remove.
CI and git hooks
# .github/workflows/ci.yml
- uses: oven-sh/setup-bun@v2
- run: bun fmt --check#!/bin/sh
# .git/hooks/pre-commit (or wherever core.hooksPath points)
bun fmt --staged--staged replaces lint-staged. It formats what the commit will contain; it never rewrites a file that also has unstaged changes. If the staged version of such a file needs formatting, Bun names it and exits 2.
Don't
- Don't install prettier, prettier-plugin-*, @biomejs/biome, dprint, lint-staged or husky for formatting.
- Don't add
.prettierrc,prettier.config.*,biome.jsonordprint.jsonin a new project; usebunfig.toml [fmt]. - Don't leave a placeholder
fmtscript; it hides the built-in formatter. bun lintis canary-only as of 1.4.4. Don't rely on it in a stable toolchain.