Prettier but in Rust: why oxfmt changes the game
A Rust-powered formatter that passes 100% of Prettier's tests, runs 30x faster, and already has Evan You's endorsement
If you care about developer tooling and the Rust-ification of JavaScript, hit follow. I write about the tools that actually move the needle.
Evan You tweeted this morning: “Let’s goooooo I have stopped thinking about formatting since using this in my own workflow. It’s so fast the step becomes invisible”
When the creator of Vue.js says a tool makes an entire category of problem vanish from his brain, we have to pay attention. The tool is oxfmt, a Rust-powered code formatter that shipped its beta today. It passes 100% of Prettier’s conformance tests, runs about 30x faster, and it might be the last formatter migration you ever do.
What is oxfmt (and what is Oxc)?
Oxfmt is the latest piece of the Oxc project (short for Oxidation Compiler), an effort to rebuild the entire JavaScript toolchain in Rust. Boshen Chen leads it. VoidZero Inc (Evan You’s company) backs it. Nearly 19K GitHub stars and a growing list of production adopters.
The ecosystem already includes some serious tools. oxc-parser is the fastest JavaScript parser available, clocking 3x faster than SWC. oxlint runs 50-100x faster than ESLint. oxc-resolver beats enhanced-resolve by 28x. oxc-transformer outpaces SWC’s transpiler by 4x.
Oxfmt is the formatter piece of this puzzle. And unlike previous “Prettier alternatives” that asked you to accept trade-offs, oxfmt’s pitch is almost comically simple: the same output, but faster. A lot faster.
The numbers don’t lie
Oxc’s benchmarks put oxfmt at 30x faster than Prettier and 3x faster than Biome on multi-file project runs. Those numbers sound made up until you actually run them.
A 10,000-file monorepo that takes Prettier 30 seconds to format? Oxfmt does it in one. Format-on-save, which already felt fast with Prettier, becomes genuinely imperceptible. CI pipelines that spent two or three minutes on formatting checks get that time back.
When your formatter is faster than your file watcher, formatting stops being a step and starts being a property of your codebase.
The speed comes from Rust, yes, but also from a set of architectural decisions that compound on each other.
100% Prettier compatibility is the killer feature
Speed is nice. But 100% Prettier compatibility is what makes oxfmt a genuine threat to the status quo.
Previous alternatives couldn’t clear this bar. Biome (which I use) sits at roughly 97% Prettier compatibility. That sounds close. It isn’t. In a large codebase, that 3% gap means hundreds of files with formatting differences. Migration PRs with thousands of changed lines that have nothing to do with your actual work. Team debates about whether the new formatting is “better” or “worse.” Edge cases that surface six months later in code review.
Oxfmt passes 100% of Prettier’s JavaScript and TypeScript conformance tests. Every single one.
In practice, that means your migration PR is empty. You swap the dependency, update the format script, and the diff is zero lines of reformatted code. No debates. No style guide discussions. No “well actually, I preferred how Prettier handled ternaries.” Identical output, just faster.
Zero-diff migration means zero-controversy migration. The best formatting debate is the one that never happens.
And the two teams actually collaborated to get here. Prettier’s test suite became oxfmt’s north star, and they worked through the gnarliest corner cases together. Not adversarial; cooperative.
How to switch in 60 seconds
The migration path is almost suspiciously easy.
Install oxfmt:
pnpm add -D oxfmtMigrate your Prettier config:
pnpm oxfmt --migrate prettierThis reads your .prettierrc (or prettier.config.js, or whatever format you’re using) and generates an equivalent oxfmt configuration. Your formatting preferences carry over.
Update your package.json scripts:
{
"scripts": {
"format": "oxfmt .",
"format:check": "oxfmt --check ."
}
}That’s it. Run pnpm format:check and watch it produce zero diffs against your existing Prettier-formatted codebase.
Editor support is already broad: VS Code, Cursor, Zed, IntelliJ, WebStorm, and Neovim all have extensions or LSP-compatible integration. If your editor speaks LSP, oxfmt speaks back.
For programmatic use, there’s a Node.js API:
{
"scripts": {
"format": "oxfmt .",
"format:check": "oxfmt --check ."
}
}Output:
const x = 1;Under the hood: why it’s fast
Speed doesn’t come from Rust alone. Plenty of Rust programs are slow. (I’ve written a few.) Oxfmt is fast because of specific architectural choices that compound on each other.
Arena allocation with bumpalo. Every AST node lives in a single memory arena. Think of it like a notepad: you write data sequentially, and when you’re done, you tear off the whole pad at once instead of erasing each note individually. Allocation is a pointer bump (nearly free), and deallocation is one operation regardless of how many nodes you created. Traditional allocators track every individual allocation and free; arena allocation skips all that bookkeeping.
Shared AST across all Oxc tools. The parser, linter, formatter, and transformer all work with the same AST representation. No serialisation between tools. No converting from one format to another. Parse once, use everywhere.
Prettier-style intermediate representation. Oxfmt uses a FormatElement IR that weighs just 24 bytes per element. The BestFitting IR element holds multiple layout variants, and the printer picks whichever fits the line width. This is the same conceptual approach Prettier uses, which is partly why achieving 100% compatibility was possible in the first place.
File-level parallelism via rayon. Each file formats independently on its own thread. On an 8-core machine, you’re formatting 8 files simultaneously. On a 16-core CI runner, 16. The work scales linearly with cores.
SIMD-accelerated gitignore matching. Even the part that figures out which files to skip is optimised. SIMD (single instruction, multiple data) lets the CPU compare multiple characters simultaneously when scanning ignore patterns, like reading a whole line of text at a glance instead of letter by letter.
The mimalloc custom allocator replaces the system allocator with one optimised for exactly this kind of workload: many small, short-lived allocations across multiple threads.
Oxfmt’s “no unit tests” philosophy sounds reckless until you realise their test suite is Prettier’s entire conformance suite. That’s arguably more tests, not fewer.
Built-in batteries: what Prettier needs plugins for
Honestly, one of Prettier’s more tedious qualities is the plugin ecosystem. Want sorted imports? Install prettier-plugin-organize-imports. Tailwind CSS class sorting? prettier-plugin-tailwindcss. package.json fields in a sensible order? Yet another plugin.
Oxfmt ships these as built-in features. Import sorting, Tailwind class sorting, and package.json field sorting all work out of the box. No extra dependencies. No plugin compatibility matrix. No wondering whether the import sorter conflicts with the Tailwind plugin.
Embedded language formatting comes built in too: CSS-in-JS, Angular templates, Vue single-file components, GraphQL queries embedded in TypeScript files. Prettier supports many of these, but each one required deliberate effort from plugin authors. In oxfmt, the shared AST architecture means the formatter understands these embedded languages natively.
The file type coverage is broad: JS, JSX, TS, TSX, JSON, JSONC, JSON5, YAML, TOML, HTML, Angular, Vue, CSS, SCSS, Less, Markdown, MDX, GraphQL, Ember, and Handlebars.
The Rust rewrite of everything
Oxfmt didn’t arrive in a vacuum. It’s the latest chapter in a pattern that’s been building since 2020.
esbuild (Go, 2020) proved that JavaScript bundling was fundamentally bottlenecked by being written in JavaScript. SWC (Rust, 2020) did the same for compilation. Turbopack (Rust, 2022) took on webpack. Biome (Rust, 2023) forked from the ashes of Rome to tackle linting and formatting. Rspack (Rust, 2023) offered a webpack-compatible alternative.
Each tool arrived at the same conclusion: the JavaScript ecosystem’s performance ceiling was its own language.
The Rome-to-Biome story is worth understanding because Oxc clearly learned from it. Rome tried to ship everything at once: parser, linter, formatter, bundler, compiler, all in one monolithic release. The company behind it ran out of money. The project collapsed. Biome was forked from the wreckage.
Oxc took the opposite approach. Ship the parser first. Get adoption. Then the linter. Then the resolver. Then the transformer. Now the formatter. Each piece gets battle-tested before the next one arrives.
Rome tried to boil the ocean and evaporated. Oxc is boiling one pot at a time.
Incremental shipping builds trust. It’s also just better engineering. Each tool validates the shared AST layer for the next one.
Who’s already using it
The adopter list already looks crazy serious.
vuejs/core is the obvious one, given Evan You’s direct involvement with VoidZero. But Vercel’s turborepo has switched. So has Sentry’s JavaScript SDK (getsentry/sentry-javascript). Hugging Face runs it on huggingface.js. The broader Oxc ecosystem has even wider adoption: Rolldown and Nuxt use oxc-parser, while Shopify, ByteDance, and Preact run oxlint in production.
These are some of the most actively maintained, highest-traffic JavaScript repositories on GitHub. When Vercel and Sentry both adopt the same formatter on day one of a beta, that tells you something.
The release cadence helps too. Oxc ships two to three times per week; v0.35.0 landed yesterday, v0.34.0 four days before that. Bugs get fixed in days, not months.
What you’re giving up (for now)
Oxfmt is a beta, and betas have gaps. Here’s what I’d want to know before switching a production monorepo.
Plugin ecosystem. Prettier’s plugin system is mature and wide-ranging. If you rely on a niche Prettier plugin for domain-specific formatting, oxfmt probably doesn’t have an equivalent yet. The built-in features cover the most common use cases, but the long tail of plugins is still Prettier’s territory.
Battle-testing. Prettier has seven-plus years of production use across millions of projects. Oxfmt has weeks. The conformance test suite covers formatting output, but it can’t cover every integration scenario, every editor quirk, or every CI environment.
Edge cases. The Oxc team acknowledges some remaining rough edges in comment placement and chain expression formatting. These are minor, but they exist.
Strengths Trade-offs
────────────────── ──────────────────
+ 30x speed - Beta stability
+ 100% compat - No plugin system
+ Built-in sorting - Edge cases
+ Zero-diff migrate - Not on crates.ioCrates.io availability. If you’re building Rust tooling that wants to use oxfmt as a library, the formatter crate isn’t published to crates.io yet.
Biome as a counterpoint. Biome is more mature today. It offers broader language support, a more established plugin model, and it’s been in production longer. If you need 97% Prettier compatibility and a proven track record, Biome is a solid choice. But if 100% compatibility and raw speed are what you’re after, oxfmt is already ahead.
The formatting problem is solved
Evan You’s tweet is worth coming back to. “I have stopped thinking about formatting.” That’s the goal of every developer tool: to become invisible. To remove a category of friction so completely that you forget it was ever there.
Formatting has been a solved problem in theory since Prettier arrived in 2017. In practice, it was always a bit too slow and a bit too visible. It still felt like a “step” rather than a property of your codebase. Oxfmt closes that gap. Sub-second formatting across your entire codebase. Zero-diff migration from Prettier. Built-in features that kill plugin dependencies.
Try it on a side project this week. Run oxfmt --check alongside Prettier in CI and compare the output. When you see identical results at 30x the speed, the switch stops being a question of “if” and becomes “why haven’t I already.”
I write about the tools reshaping JavaScript infrastructure. If staying ahead of the toolchain curve matters to you, hit follow so you catch the next one.

