Plate 05
oxfmt 0.72: native Markdown formatter, Prettier 3.9.9 parity test, sorted imports in code fences (5 Oct 2026)
oxfmt 0.72.0 (5 Oct 2026) swaps its Prettier-backed Markdown path for the native oxc_formatter_markdown (breaking). ShopperCove formatted 221 Markdown drafts with oxfmt 0.71.0, 0.72.0 and Prettier 3.9.9: byte-identical output, ~2 s vs ~16 ms. Plus opt-in import sorting inside code fences, the documented divergences, ignore-file and LSP fixes. No affiliate links.
Aditya Challa5 min read
No affiliate links. This is a frontend tooling note based on the oxfmt v0.72.0 release, PR #27256, the npm registry, and a scratch test on ShopperCove’s own Markdown drafts. Nothing in ShopperCove’s production build was changed for this article.
Why oxfmt 0.72 matters if you use Prettier
oxfmt is the Oxc project’s Prettier-compatible formatter, and it is also bundled in Vite+. Up to 0.71.0 it formatted Markdown by handing the file to a bundled Prettier (0.71.0 bumped that to Prettier 3.9.9). Version 0.72.0 shipped on 5 Oct 2026 (npm 11:03 UTC / 16:33 IST; GitHub release 11:04 UTC / 16:34 IST). It has one breaking change:
parser:markdownfiles are now formatted byoxc_formatter_markdown, Oxc’s own Rust Markdown formatter, instead of Prettier (#27256, merged 05:17 UTC / 10:47 IST).
The PR says the output is "basically the same" as Prettier 3.9.9 and already includes some fixes Prettier has not released yet. Differences are recorded in DIVERGENCES.md.
Because code fences are now formatted by oxc_formatter instead of Prettier’s babel/typescript path, sortImports and sortTailwindcss now apply to JS/TS inside Markdown fences. Fence languages are detected with Shiki language names. Block ::: directives work in both VitePress (::: tip) and remark-directive (:::tip) style.
ShopperCove test: 221 Markdown drafts, 0.71.0 vs 0.72.0 vs Prettier 3.9.9
On 5 Oct 2026 we installed oxfmt@0.71.0, oxfmt@0.72.0 and prettier@3.9.9 in separate scratch folders on an 8-thread Linux box with Node 20.19.2. We then formatted copies of 221 ShopperCove body-clean-cms.md drafts (about 2 MB) using default options and an empty .oxfmtrc.json.
| Run | Wall time reported by the tool | Output vs Prettier 3.9.9 |
|---|---|---|
| oxfmt 0.71.0 (Prettier-backed Markdown) | 1,981–2,135 ms (3 runs) | Byte-identical on all 221 |
| oxfmt 0.72.0 (native Markdown) | 16–17 ms (3 runs) | Byte-identical on all 221 |
Both versions rewrote 186 of the 221 drafts (mostly * → _ emphasis, list markers, and table padding). They produced exactly the same bytes as each other and as Prettier 3.9.9. On this corpus the switch was invisible except for speed, roughly 120× faster. Your numbers will differ. Treat this as one site’s smoke test, not a benchmark.
Two differences we did reproduce
On a small hand-written file:
- Sorted imports inside fences. With
"experimentalSortImports": {}in.oxfmtrc.json, 0.72.0 reordered a```jsfence (reactbeforezod, then a blank line before the relative./aimport). 0.71.0 and Prettier left the order alone. Without that config, 0.72.0 did not reorder anything. If your docs or MDX snippets are meant to show a specific import order, review the first 0.72 diff. - Pipe rows in a list continuation. A list item followed by unindented
| not | table |and|---|---|lines (a lazy continuation, not a real table) was printed by 0.72.0 as one line:| not | table | |---|---|. 0.71.0 and Prettier kept two lines. This is the documented wrapped-block-starts divergence. Oxc joins the lines on purpose so the delimiter row cannot turn into a table the next time the file is parsed. Real tables separated by a blank line formatted the same in all three tools.
Chinese/Japanese line breaks were also preserved under every proseWrap setting (#27331, aligned with the unreleased Prettier 3.10).
Other fixes in 0.72.0
From the release notes:
- CSS: embedded CSS is now parsed as block contents, plus layout fixes found by running against the mdn-content repo (CSS inside Markdown).
- Ignore files: a negated pattern such as
!vendor/keep.tsno longer re-includes a file under an excludedvendor/directory when formatting explicit paths, stdin, or in the LSP (#27237). This now matches Git and Prettier. - LSP:
.prettierignoreis reloaded when the file changes. Stdin mode checks global ignores before nested config and renders diagnostics with source. - JS formatter:
quoteProps: "consistent"now handles patterns and computed keys; comments between a callee and its opener stay on the callee side; embedded template layout is decided from the AST. - JSON: arrays and objects that contain only a block comment are flattened.
- Performance: an exponential
will_breakcheck on nested interned content was removed, and the Markdown IR buffer is pre-allocated.
The same-day oxlint 1.87.0 (rule suggestions and a11y fixes) is covered separately.
Upgrade checklist
- Pin
oxfmt@0.72.0on a branch and runoxfmt --checkacross**/*.mdand**/*.mdx. Expect few or no diffs if you were already on 0.71.0 / Prettier 3.9.9. - If you enable
experimentalSortImportsor Tailwind class sorting, expect new diffs inside Markdown code fences. Commit them separately from content changes. - Search the diff for lines like
| … | |---|inside lists (the wrapped-block-starts case) and for leading***thematic breaks (the leading-thematic-break divergence). - If you rely on
!patternre-includes under an ignored directory, note that explicit-path formatting now skips those files. - Teams formatting with Prettier directly can stay on Prettier 3.9.9 (latest on npm as of 5 Oct 2026). Nothing changes for you until you adopt oxfmt or Vite+.
Bottom line
oxfmt 0.72.0 drops Prettier from its Markdown path. On ShopperCove’s 221 drafts the output stayed byte-identical to Prettier 3.9.9, and formatting took ~16 ms instead of ~2 s. The visible changes are opt-in import/Tailwind sorting inside fences and a short, documented list of intentional divergences. Pin, run --check, and review the first diff.
Sources
- https://github.com/oxc-project/oxc/releases/tag/oxfmt_v0.72.0
- https://github.com/oxc-project/oxc/pull/27256
- https://github.com/oxc-project/oxc/blob/main/crates/oxc_formatter_markdown/DIVERGENCES.md
- https://github.com/oxc-project/oxc/releases/tag/oxfmt_v0.71.0
- https://github.com/oxc-project/oxc/pull/27237
- https://github.com/oxc-project/oxc/pull/27331
- https://registry.npmjs.org/oxfmt
- https://oxc.rs/docs/guide/usage/formatter.html
- https://github.com/prettier/prettier/releases/tag/3.9.9
Related
- https://www.shoppercove.com/blog/oxlint-1-87-react-suggestions-a11y-fixes-october-2026
- https://www.shoppercove.com/blog/vite-plus-1-0-unified-toolchain-october-2026
- https://www.shoppercove.com/blog/biome-2-5-15-type-inference-nursery-rules-october-2026
- https://www.shoppercove.com/blog/eslint-10-12-release-october-2026
- https://www.shoppercove.com/blog/typescript-eslint-8-71-no-unsafe-enum-assignment-october-2026
- https://www.shoppercove.com/blog/astro-starlight-0-42-popover-js-dist-october-2026
- https://www.shoppercove.com/blog/rspack-2-2-8-resolver-cache-memory-october-2026
- https://www.shoppercove.com/blog/bun-1-4-2-elysia-als-cmyk-jpeg-october-20
Lab evidence
What I found running this
Sources read 5 Oct 2026 (Asia/Calcutta): npm registry oxfmt latest 0.72.0 published 2026-10-05T11:03:48Z (16:33 IST); GitHub release oxfmt_v0.72.0 11:04:20Z; PR #27256 merged 05:17:36Z (10:47 IST) — BREAKING parser:markdown via oxc_formatter_markdown, sortImports/sortTailwindcss now apply in fences, Shiki fence langs, ::: directives; 0.71.0 bumped bundled Prettier to 3.9.9; DIVERGENCES.md read (wrapped-block-starts, leading-thematic-break, url-escaping…). Hands-on in /tmp scratch on box (8 threads, Node 20.19.2): installed oxfmt@0.71.0, oxfmt@0.72.0, prettier@3.9.9; formatted copies of 221 ShopperCove body-clean-cms.md drafts (~2 MB) with empty .oxfmtrc.json: 0.71.0 'Finished in' 1981/2123/2135 ms, 0.72.0 16/16/17 ms; diff -rq 0.71 vs 0.72 vs Prettier = 0 files differ; 186/221 drafts rewritten vs source. Small fixture: with experimentalSortImports {} 0.72 reordered a js fence (react before zod, blank line before ./a), 0.71/Prettier did not; without config no reorder. List-item lazy '| not | table |' + '|---|---|' lines joined to one line by 0.72 only (documented wrapped-block-starts); proper table identical in all three. Prettier npm latest still 3.9.9 (23 Sep). No production build changed. No affiliate.
Related links
Plate 51
Biome 2.5.15: type-inference speedups, nursery rules, HTML formatter (30 Sep 2026)
Biome published @biomejs/biome@2.5.15 on 30 September 2026: type-inference and HTML formatter performance, plus nursery rules for React defaults, Svelte runes, logical CSS, and more. ShopperCove upgrade checklist only; no affiliate.
5 Oct 2026
Plate 78
oxlint 1.87.0: React suggestion fixes + jsx-a11y hardening (5 Oct 2026)
oxlint published v1.87.0 on 5 October 2026: suggestion support for three React/unicorn rules and jsx-a11y/label/mouse/lang hardening plus other fixes. npm latest 1.87.0 confirmed; ShopperCove docs checklist only; no affiliate.
5 Oct 2026
Plate 63
Biome vs ESLint: Should You Switch? 0.41s vs 18.7s
Biome 2.5.15 check vs ESLint 9.39.4 + Prettier 3.8.4 on react-hook-form (317 files): 0.41 s vs 18.7 s sequential stack (ESLint 13.58 s, Prettier check 5.22 s). migrate eslint: 54/476 direct, ~50% covered. Biome 200 errors/427 warnings vs ESLint 0/562; 9 format diffs; 287 noExplicitAny from recommended.
5 Oct 2026