Migrate from oxfmt to bun fmt

bun fmt reads your .oxfmtrc.json and prints what oxfmt 0.72 prints. In most projects you only change the command.

Start with --doctor. It shows what Bun will do with your config, and it doesn't format or write anything.

terminal
bun fmt --doctor
Using .oxfmtrc.json (oxfmt config)

    3 files are formatted natively

Still needed:   oxfmt (the "format" script runs it)

Change the scripts.

package.json
{
  "scripts": {
    "format": "oxfmt", 
    "format:check": "oxfmt --check", 
    "format": "bun fmt", 
    "format:check": "bun fmt --check" 
  }
}

Flags and arguments stay the same. Change CI and Git hooks too.

If your script is called fmt, don't skip this: bun fmt runs a fmt script when package.json has one, so you'd still get oxfmt.


Check that nothing changes. With an oxfmt config, a run prints what oxfmt prints.

terminal
bun fmt --check
$ bun fmt --check
Checking formatting...

All matched files use the correct format.
Finished in 4ms on 3 files using 64 threads.

If you're on a version of oxfmt before 0.72, a few files change once, like when you upgrade oxfmt.


Run --doctor again. No script runs oxfmt anymore, so you can uninstall it.

You can remove: oxfmt
Not checked:    other tools' configs, CI files, Git hooks
terminal
bun remove oxfmt

No .oxfmtrc.json? Add one with {} in it first. Without a config file, the oxfmt dependency is how Bun knows to format like oxfmt and not like Prettier.


Bun reads everything oxfmt reads:

  • .oxfmtrc.json, .oxfmtrc.jsonc, and oxfmt.config.ts, with overrides and ignorePatterns
  • The fmt key of vite.config.ts, if you use vite-plus
  • Every option, including sortImports, sortPackageJson, sortTailwindcss, jsdoc, and svelte
  • // oxfmt-ignore and // prettier-ignore comments
  • Every flag of oxfmt 0.72 except --lsp and --migrate

It also follows oxfmt's defaults: lines wrap at 100 columns, every .gitignore in the repository counts, TOML files are formatted, and .prettierrc is ignored.


Still have a .prettierrc next to .oxfmtrc.json? Bun uses .oxfmtrc.json and tells you so. Delete the one you no longer use, or pick one with --config.

note: Using .oxfmtrc.json. .prettierrc is ignored. Use --config to pick it.

Keep oxfmt if your editor's oxc extension uses it. bun fmt has no language server.


Differences from oxfmt#

If bun fmt and oxfmt 0.72 print different code, that's a bug. Open an issue. These differences are intentional:

  • The output is oxfmt 0.72's, whatever version you had installed.
  • No --lsp or --migrate.
  • Errors and warnings are worded differently.
  • sortTailwindcss uses your project's tailwindcss. If it isn't installed, Bun leaves the classes as they are. oxfmt sorts them with a Tailwind CSS of its own.
  • A stylesheet or config that doesn't exist is an error, and the files with classes aren't formatted. oxfmt leaves the classes unsorted and exits with code 0.
  • sortPackageJson only moves keys. oxfmt parses package.json and writes it back, which turns 1e3 into 1000.0 and "\u00e9" into "é", drops all but the last of two members with the same key, and drops whatever isn't a string from lists like keywords. Bun leaves every value as you wrote it. It also sorts a file with a trailing comma, which oxfmt leaves unsorted.
  • An invalid TOML file is left alone, with a warning. oxfmt rewrites the parts it can read.
  • A file that isn't valid UTF-8 is still formatted, and the invalid bytes are kept. oxfmt exits with code 2.
  • A function's only parameter doesn't move on the second run. When an object type in the return type doesn't fit on the line, oxfmt gives the parameter its own line, then joins m(a: string): { again the next time it runs. Bun prints the joined form the first time.
  • Where oxfmt's output changes what a file means, Bun's differs. That's rare. In TOML oxfmt joins the lines of an inline table with a comment, which comments out the rest of the table. Bun keeps one entry per line. In Svelte oxfmt drops the comment in {#if a /* b */}, the space in <hr />some <b>words</b>, and an empty {:catch}, and it empties the <script> after a comment that mentions <style>. Bun keeps them.

See also: