Back to Turborepo

Oxc (oxlint and oxfmt)

apps/docs/content/docs/guides/tools/oxc.mdx

2.9.95.0 KB
Original Source

import { CreateTurboCallout } from "./create-turbo-callout.tsx";

Oxc is a collection of high-performance JavaScript and TypeScript tools written in Rust, including oxlint (a fast linter) and oxfmt (a fast formatter).

<CreateTurboCallout />

Using Oxc tools with Turborepo

Similar to Biome, oxlint and oxfmt are extraordinarily fast tools. For this reason, we recommend using Root Tasks rather than creating separate scripts in each of your packages.

<Callout type="info" title="Caching behavior"> Using oxlint or oxfmt at the root of the project will result in cache misses for all tasks when you upgrade versions or change configuration. If you prefer the tradeoff of higher cache hit ratios in these situations over less configuration, you can still run these tools in separate scripts like the other recommendations in our guides. </Callout>

Setting up oxlint

Install oxlint

First, install oxlint in your repository:

<PackageManagerTabs> <Tab value="pnpm">
bash
pnpm add --save-dev -w oxlint
</Tab> <Tab value="yarn">
bash
yarn add --dev oxlint
</Tab> <Tab value="npm">
bash
npm install --save-dev oxlint
</Tab> <Tab value="bun">
bash
bun add --dev oxlint
</Tab> </PackageManagerTabs>

Create scripts

Add scripts to the root package.json of your repository:

json
{
  "scripts": {
    "lint": "oxlint .",
    "lint:fix": "oxlint --fix ."
  }
}

Create root tasks

Register the scripts to Turborepo as Root Tasks:

json
{
  "tasks": {
    "//#lint": {},
    "//#lint:fix": {
      "cache": false
    }
  }
}

You can now run turbo run lint to lint your entire repository.

<Callout type="warn" title="Type-aware linting"> If you enable [type-aware linting rules](https://oxc.rs/docs/guide/usage/linter/config#type-aware-linting) in oxlint, the linter needs TypeScript type information to work correctly. This means any dependencies that must be built before type-checking (such as [Compiled Packages](/docs/core-concepts/internal-packages#compiled-packages) in your monorepo) also need to be built before linting.

For example, to build Compiled Packages before running formatting and linting:

bash
turbo run build --filter=./packages/* && turbo run lint

Alternatively, you can switch to per-package lint tasks with dependsOn: ["^build"] to let Turborepo handle the ordering for you.

</Callout>

Setting up oxfmt

oxfmt is a fast code formatter for JavaScript and TypeScript, designed to be a drop-in replacement for Prettier.

<Callout type="warn" title="oxfmt is experimental"> oxfmt is currently in alpha and may not have full feature parity with Prettier. Check the [oxfmt documentation](https://oxc.rs/docs/guide/usage/formatter) for the latest status and supported options. </Callout>

Install oxfmt

Install oxfmt as a dev dependency:

<PackageManagerTabs> <Tab value="pnpm">
bash
pnpm add --save-dev -w oxfmt
</Tab> <Tab value="yarn">
bash
yarn add --dev oxfmt
</Tab> <Tab value="npm">
bash
npm install --save-dev oxfmt
</Tab> <Tab value="bun">
bash
bun add --dev oxfmt
</Tab> </PackageManagerTabs>

Create scripts

Add formatting scripts to the root package.json:

json
{
  "scripts": {
    "format": "oxfmt --check",
    "format:fix": "oxfmt ."
  }
}

Create root tasks

Register the scripts to Turborepo:

json
{
  "tasks": {
    "//#format": {},
    "//#format:fix": {
      "cache": false
    }
  }
}

You can now run turbo run format to check formatting and turbo run format:fix to format your code.

Using oxlint and oxfmt together

For repositories using both tools, you can orchestrate them with a unified quality task:

json
{
  "scripts": {
    "lint": "oxlint .",
    "lint:fix": "oxlint --fix .",
    "format": "oxfmt --check",
    "format:fix": "oxfmt ."
  }
}
json
{
  "tasks": {
    "//#quality": {
      "dependsOn": ["//#lint", "//#format"]
    },
    "//#quality:fix": {
      "dependsOn": ["//#lint:fix", "//#format:fix"]
    },
    "//#lint": {},
    "//#lint:fix": {
      "cache": false
    },
    "//#format": {},
    "//#format:fix": {
      "dependsOn": ["//#lint:fix"],
      "cache": false
    }
  }
}

With this configuration:

  • Run turbo run quality to check both linting and formatting in parallel (safe because neither modifies files)
  • Run turbo run quality:fix to fix both linting and formatting issues, with formatting running after lint fixes to avoid file write race conditions