CtrlK
BlogDocsLog inGet started
Tessl Logo
SkillPublic

migrate-oxfmt

Guide for migrating a project from Prettier or Biome to Oxfmt. Use when asked to migrate, convert, or switch a project's formatter from Prettier or Biome to Oxfmt.

Quality

89%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

Passed

No findings from the security scan

SKILL.md
Quality
Evals
Security

This skill guides you through migrating a project from Prettier or Biome to Oxfmt.

Overview

Oxfmt is a high-performance, Prettier-compatible code formatter. Most Prettier options are supported directly.

An automated migration tool is built into Oxfmt, supporting both Prettier and Biome as migration sources.

Step 1: Run Automated Migration

First, decide whether the automated tool fits:

  • Static config (JSON, or a JS/TS config that just exports a plain object): use --migrate below.
  • Dynamic JS/TS config (logic such as environment branches or computed values): --migrate writes only a resolved snapshot of the values, and the logic does not survive (a warning is printed). Port the logic to oxfmt.config.ts manually with the option mappings in this guide.
  • Nested per-directory configs: --migrate only handles the config in the current directory. Run it again in each nested directory (see "Nested Config" in Step 2).

From Prettier

npx oxfmt@latest --migrate prettier

This will:

  • Find your Prettier config in the current directory, in the same order as Prettier
    • Supported: package.json (prettier field), .prettierrc (JSON only), .prettierrc.json, and JS/TS configs (.prettierrc.*, prettier.config.*)
    • Shareable configs (e.g. "prettier": "@company/prettier-config") are resolved
    • YAML, JSON5 and TOML configs are not supported. Convert them to JSON or JS first
  • Create .oxfmtrc.json with migrated options
    • Only Prettier-compatible options are migrated, others are skipped with a warning
  • Migrate overrides
    • overrides[].options.parser is migrated to associations[].language
  • Migrate .prettierignore patterns to ignorePatterns
  • Migrate prettier-plugin-tailwindcss options to sortTailwindcss
  • Migrate prettier-plugin-svelte options to svelte (svelteSortOrder → sortOrder, svelteAllowShorthand → allowShorthand, svelteIndentScriptAndStyle → indentScriptAndStyle)
  • Migrate prettier-plugin-astro options to astro (astroAllowShorthand → allowShorthand, astroSkipFrontmatter → skipFrontmatter, astroCompressHTML → compressHTML)
  • Detect prettier-plugin-packagejson and enable sortPackageJson
  • Skip other plugins with a warning

Notes (Prettier):

  • Fails if no Prettier config is found in the current directory. Use --init to create a blank .oxfmtrc.json instead.
  • The generated .oxfmtrc.json may not be formatted yet. Run oxfmt after migration.

From Biome

npx oxfmt@latest --migrate biome

This will:

  • Find and read biome.json or biome.jsonc
  • Create .oxfmtrc.json with migrated options
  • Migrate negated patterns from files.includes to ignorePatterns
  • Map Biome's two-level config (formatter.* and javascript.formatter.*) to Oxfmt options

Biome option mapping:

BiomeOxfmt
formatter.indentStyle ("tab"/"space")useTabs (true/false)
formatter.indentWidthtabWidth
formatter.lineWidthprintWidth
javascript.formatter.quoteStylesingleQuote
javascript.formatter.jsxQuoteStylejsxSingleQuote
javascript.formatter.quoteProperties ("asNeeded")quoteProps ("as-needed")
javascript.formatter.trailingCommastrailingComma
javascript.formatter.semicolons ("always"/"asNeeded")semi (true/false)
javascript.formatter.arrowParentheses ("asNeeded")arrowParens ("avoid")
javascript.formatter.bracketSameLinebracketSameLine
formatter.bracketSpacingbracketSpacing
formatter.attributePosition ("multiline")singleAttributePerLine (true)

Notes (Biome):

  • For formatter.* options in the table, a javascript.formatter.* value of the same name takes precedence when present. bracketSameLine is read only from javascript.formatter.bracketSameLine.
  • Options not set in biome.json are written to .oxfmtrc.json with Biome's default values explicitly (e.g. printWidth: 80, useTabs: true), so the output preserves Biome's formatting behavior.
  • If no Biome config is found, creates a blank .oxfmtrc.json instead.
  • overrides cannot be auto-migrated and must be converted manually (a warning is printed if detected).

Notes (both sources):

  • Fails if an Oxfmt config (.oxfmtrc.json, .oxfmtrc.jsonc, oxfmt.config.ts or oxfmt.config.mts) already exists. Delete it first if you want to re-run.

Step 2: Review Generated Config

After migration, review the generated .oxfmtrc.json for these key differences:

printWidth

Prettier and Biome default is 80, Oxfmt default is 100. The migration tool sets printWidth: 80 if not specified in your source config. Decide whether to keep 80 or adopt 100.

Unsupported Options (Prettier only)

Any option not in "Prettier-Compatible Options" below is skipped with a warning, including options of unsupported plugins (e.g. importOrder). Notable ones:

OptionStatus
endOfLine: "auto"Not supported. Use "lf" or "crlf" explicitly
experimentalTernariesNot supported
requirePragma, insertPragmaNot supported
parserSkipped at top-level. In overrides, migrated to associations if known
pluginsOnly known plugins are migrated (see Step 1)

Regex values (e.g. "/^my-/") in tailwindFunctions / tailwindAttributes are also skipped with a warning, Oxfmt only supports literal strings there.

sortPackageJson (Prettier only)

Enabled by default in Oxfmt, but the migration tool disables it unless prettier-plugin-packagejson was detected. Review whether you want this enabled.

Note: Oxfmt's sorting algorithm differs from prettier-plugin-packagejson.

embeddedLanguageFormatting (Prettier only)

Embedded language formatting (e.g., CSS-in-JS) generally works.

overrides

Prettier overrides are auto-migrated. Unsupported options in them are skipped with a warning, so review the result.

overrides[].options.parser is migrated to associations, which tells Oxfmt which language to use for matched files:

{
  "associations": [{ "files": ["*.svg"], "language": "html" }]
}

language is a Shiki language id (as in Markdown code fences), not a Prettier parser name (e.g. angular-html instead of angular, typescript instead of babel-ts).

Biome overrides cannot be auto-migrated. Convert manually:

{
  "overrides": [
    {
      "files": ["*.md"],
      "excludeFiles": ["CHANGELOG.md"],
      "options": { "tabWidth": 4 }
    }
  ]
}

(excludeFiles is optional.)

Nested Config

Oxfmt supports nested configuration files: a config in a subdirectory applies to files under that directory. Pass --disable-nested-config to opt out and use only the root config.

However, --migrate only migrates the config in the current directory, and does not walk subdirectories. If the project has per-directory Prettier or Biome configs, run --migrate in each of those directories.

Prettier-Compatible Options

These options transfer directly with the same behavior: printWidth, tabWidth, useTabs, semi, singleQuote, jsxSingleQuote, quoteProps, trailingComma, arrowParens, bracketSpacing, bracketSameLine, objectWrap, experimentalOperatorPosition, endOfLine, proseWrap, htmlWhitespaceSensitivity, singleAttributePerLine, vueIndentScriptAndStyle, embeddedLanguageFormatting

Step 3: Configure Oxfmt Extensions

Oxfmt offers features not available in Prettier:

sortImports

Sort import statements, inspired by eslint-plugin-perfectionist/sort-imports (disabled by default):

{
  "sortImports": {
    "partitionByNewline": true,
    "newlinesBetween": false
  }
}

Other options: partitionByComment, sortSideEffects, order, ignoreCase, internalPattern, groups, customGroups.

sortTailwindcss

Replaces prettier-plugin-tailwindcss. Auto-migrated with renamed options:

Prettier (top-level)Oxfmt (sortTailwindcss.*)
tailwindConfigconfig
tailwindStylesheetstylesheet
tailwindFunctionsfunctions
tailwindAttributesattributes
tailwindPreserveWhitespacepreserveWhitespace
tailwindPreserveDuplicatespreserveDuplicates

Other Extensions

OptionDefaultDescription
insertFinalNewlinetrueWhether to add a final newline at end of file
sortPackageJsontrueSort package.json keys. Set { "sortScripts": true } to also sort scripts
jsdocdisabledFormat JSDoc comments. Set true or an options object for fine-grained control
sveltedisabledSvelte formatting options, replacing prettier-plugin-svelte (auto-migrated)
astrodisabledAstro formatting options, replacing prettier-plugin-astro (auto-migrated)
associations[]Format matched files as the given language (e.g. *.svg as html)

Step 4: Update CI and Scripts

Replace formatter commands with Oxfmt:

# Before (Prettier)
npx prettier --write .
npx prettier --check .

# Before (Biome)
npx biome format --write .
npx biome check .

# After
npx oxfmt@latest
npx oxfmt@latest --check

Common CLI Options

Prettier / BiomeOxfmt
prettier --write . / biome format --write .oxfmt (default: cwd, --write mode)
prettier --check . / biome check .oxfmt --check
prettier --list-different .oxfmt --list-different
prettier --config pathoxfmt --config path
prettier --ignore-path .prettierignoreoxfmt --ignore-path .prettierignore
cat file | prettier --stdin-filepath=file.tscat file | oxfmt --stdin-filepath=file.ts

File Type Coverage

  • JS/TS, JSON/JSONC/JSON5, CSS/SCSS/Less, GraphQL, YAML, Markdown, TOML: Formatted natively by Oxfmt
  • HTML, Vue, Svelte, Astro, etc.: Delegated to Prettier internally (when using npx oxfmt)

Step 5: Review Formatting Changes

Run npx oxfmt@latest and review the diff.

Oxfmt uses Prettier's output as its baseline, but deliberately fixes cases where Prettier's behavior is a bug or inconsistent across similar cases. Before treating a difference from Prettier as a migration mistake or an Oxfmt bug, check Known Divergences:

  • Listed there: intentional. Keep Oxfmt's output, do not try to reproduce Prettier's output with options or ignore comments.
  • Not listed, and not explained by a config difference (e.g. printWidth): likely an Oxfmt bug. Tell the user, who can report it at https://github.com/oxc-project/oxc/issues.

Tips

  • Config file: .oxfmtrc.jsonc and oxfmt.config.ts are also supported as auto-discovered config file names, in addition to .oxfmtrc.json. --migrate and --init only generate .oxfmtrc.json; keep it as-is unless the user explicitly asks for another format or the source config had logic to preserve (see Step 1).
  • EditorConfig: Oxfmt reads .editorconfig automatically for useTabs, tabWidth, endOfLine, insertFinalNewline, printWidth, and singleQuote. Options in .oxfmtrc.json take precedence.
    • Nearest one only, does not respect root
  • CI: Use npx oxfmt@latest --check to enforce formatting in CI.
  • LSP: Run oxfmt --lsp for editor integration via Language Server Protocol.
  • Schema support: Add "$schema": "./node_modules/oxfmt/configuration_schema.json" to .oxfmtrc.json for editor autocompletion.
  • Init: Run npx oxfmt@latest --init to create a default .oxfmtrc.json without migration.

References

Repository

oxc-project/oxc

Path

.agents/skills/migrate-oxfmt/SKILL.md

Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.