Summary
Proof-of-concept investigation into replacing Prettier with oxfmt (the oxc formatter) for the monorepo. Result: large speed win with low churn for the JS/TS/JSON bulk. oxfmt can't format a few file types, so the proposal is a hybrid where oxfmt owns the bulk, tsp format owns .tsp, and Prettier is kept only for .astro + shell.
Tested with oxfmt 0.59.0 (npm hybrid build).
Key results
- ~30× faster on the JS/TS/JSON bulk:
oxfmt --check = ~2.7s on 2947 files vs Prettier format:check = ~80–100s.
- Low churn: only 55 / 2947 files (1.9%) differ — genuine formatting deltas (union-type line-breaking, arrow-arg wrapping), not import reordering.
- No JSON / YAML / CSS churn — byte-identical to Prettier.
.prettierrc migrated cleanly via oxfmt --migrate=prettier (all core options + every .prettierignore pattern). Only the 4 plugins are dropped (expected).
Coverage
oxfmt natively handles: JS/TS/TSX, JSON, YAML, Markdown, CSS, GraphQL, TOML.
Gaps (must live elsewhere):
| File type |
Count |
Plan |
.tsp |
356 |
tsp format (compiler's own formatter; the prettier plugin just wraps it) |
.astro |
47 |
Unsupported in 0.59 → residual Prettier |
.sh |
1 (packages/standalone/install.sh) |
No shell support → residual Prettier |
Benchmarks (M-series mac, 10 threads)
| Step |
Files |
Wall time |
Prettier format:check (current) |
~all |
~80–100s |
oxfmt --check . |
2947 |
~2.7s |
tsp format --check |
324 |
~1.8s |
Prettier residual (*.{astro,sh}) |
48 |
~4.1s |
| Proposed combined pipeline |
— |
~9s |
Churn detail (the 55 files)
26 .ts, 25 .tsx, 4 .md. Representative diffs:
- Union types that fit within
printWidth are broken to one member per line with a leading | by oxfmt, where Prettier 3.9.5 keeps them on one wrapped line.
arr.map((x): T => ({...})) — oxfmt wraps the callback argument differently.
One-time reformats; the resulting style is stable and self-consistent.
⚠️ Do NOT enable sortImports: it re-sorts with the perfectionist algorithm (≠ prettier-plugin-organize-imports order) and churn jumps to 1337 files (45%).
Import organizing — behavioral gap
- Current
prettier-plugin-organize-imports sorts + removes unused imports.
- oxfmt
sortImports is off by default; when on it only sorts (different order), never removes unused.
- oxlint already has
no-unused-vars: error, which flags unused imports (blocks CI) but does not auto-remove them on --fix.
- Recommendation: keep
sortImports off. Either (a) drop import-organizing and rely on oxlint, or (b) keep prettier-plugin-organize-imports as a residual TS/JS step. (a) is cleaner; (b) preserves exact current behavior.
Proposed end-state
- oxfmt owns: JS/TS/TSX/MJS, JSON, YAML, Markdown, CSS, GraphQL, TOML.
tsp format owns: .tsp.
- Prettier (residual) owns only:
.astro + .sh (slim config, astro+sh plugins only).
Editor / CI follow-ups (not yet applied)
- VS Code: install the oxc extension (
oxc.oxc-vscode, oxfmt via LSP); set per-language editor.defaultFormatter (oxfmt for JS/TS/JSON/CSS/MD/YAML, TypeSpec ext for .tsp, Prettier for .astro/shell). Current shared .vscode/settings.json hardcodes esbenp.prettier-vscode.
- CI (
.github/workflows/consistency.yml): replace the prettier-plugin build + pnpm run format:check with the oxfmt/tsp/residual pipeline (oxfmt needs no build; tsp format still needs the compiler built).
Risks / open items
- One-time 55-file reformat lands a slightly different (but stable) JS/TS style vs Prettier.
- Loss of automatic unused-import removal (mitigated by oxlint
no-unused-vars).
.astro unsupported today — track oxc Tier-4 progress to eventually drop the Prettier residual.
- oxfmt is Beta (Feb 2026); pin the version and re-verify churn on upgrades.
tsp format requires the compiler to be built before running (same as today's prettier-plugin build step).
Findings from a hands-on PoC that wired oxfmt/tsp format/residual-Prettier scripts side-by-side with the existing Prettier scripts (no repo-wide reformat performed).
Summary
Proof-of-concept investigation into replacing Prettier with oxfmt (the oxc formatter) for the monorepo. Result: large speed win with low churn for the JS/TS/JSON bulk. oxfmt can't format a few file types, so the proposal is a hybrid where oxfmt owns the bulk,
tsp formatowns.tsp, and Prettier is kept only for.astro+ shell.Tested with oxfmt 0.59.0 (npm hybrid build).
Key results
oxfmt --check= ~2.7s on 2947 files vs Prettierformat:check= ~80–100s..prettierrcmigrated cleanly viaoxfmt --migrate=prettier(all core options + every.prettierignorepattern). Only the 4 plugins are dropped (expected).Coverage
oxfmt natively handles: JS/TS/TSX, JSON, YAML, Markdown, CSS, GraphQL, TOML.
Gaps (must live elsewhere):
.tsptsp format(compiler's own formatter; the prettier plugin just wraps it).astro.shpackages/standalone/install.sh)Benchmarks (M-series mac, 10 threads)
format:check(current)--check .tsp format --check*.{astro,sh})Churn detail (the 55 files)
26
.ts, 25.tsx, 4.md. Representative diffs:printWidthare broken to one member per line with a leading|by oxfmt, where Prettier 3.9.5 keeps them on one wrapped line.arr.map((x): T => ({...}))— oxfmt wraps the callback argument differently.One-time reformats; the resulting style is stable and self-consistent.
sortImports: it re-sorts with the perfectionist algorithm (≠prettier-plugin-organize-importsorder) and churn jumps to 1337 files (45%).Import organizing — behavioral gap
prettier-plugin-organize-importssorts + removes unused imports.sortImportsis off by default; when on it only sorts (different order), never removes unused.no-unused-vars: error, which flags unused imports (blocks CI) but does not auto-remove them on--fix.sortImportsoff. Either (a) drop import-organizing and rely on oxlint, or (b) keepprettier-plugin-organize-importsas a residual TS/JS step. (a) is cleaner; (b) preserves exact current behavior.Proposed end-state
tsp formatowns:.tsp..astro+.sh(slim config, astro+sh plugins only).Editor / CI follow-ups (not yet applied)
oxc.oxc-vscode, oxfmt via LSP); set per-languageeditor.defaultFormatter(oxfmt for JS/TS/JSON/CSS/MD/YAML, TypeSpec ext for.tsp, Prettier for.astro/shell). Current shared.vscode/settings.jsonhardcodesesbenp.prettier-vscode..github/workflows/consistency.yml): replace the prettier-plugin build +pnpm run format:checkwith the oxfmt/tsp/residual pipeline (oxfmt needs no build;tsp formatstill needs the compiler built).Risks / open items
no-unused-vars)..astrounsupported today — track oxc Tier-4 progress to eventually drop the Prettier residual.tsp formatrequires the compiler to be built before running (same as today's prettier-plugin build step).Findings from a hands-on PoC that wired oxfmt/
tsp format/residual-Prettier scripts side-by-side with the existing Prettier scripts (no repo-wide reformat performed).