An Oxc-first workflow package for Oxlint and Oxfmt
I have been following the Oxc project for quite a while. After seeing it enter the 1.x line some time ago, I had wanted to put together a configuration for it, and over the past few days I finally found time to work on it.
At the current stage, however, Oxlint still cannot fully replace ESLint. It has to be Oxlint first and ESLint second. The good part is that the two can work together perfectly, so from a project's perspective you can still solve code quality issues through a single linting workflow. Oxfmt, on the other hand, can fully replace Prettier's native rules, although some plugins still require trade-offs. For example, I have to temporarily give up Pangu spacing formatting for Markdown.
Because both linting setups need to work together, I have not formally named this package oxc-config yet. For now, I simply call it Integration, an integration solution or, more precisely, a workflow.
This is an open source project I published on GitHub. If it helps you, please give bassist a Star.
@bassist/oxc-integration is an Oxc-first workflow package for projects that want typed oxlint.config.ts and oxfmt.config.ts setups today, while still keeping an ESLint fallback available where framework coverage is not yet enough.
Usage
Using this package usually follows four steps:
- Install dependencies (See: Install)
- Add
oxlint.config.ts(See: Oxlint Quick Start) - Add
oxfmt.config.ts(See: Oxfmt Quick Start) - Add
eslint.config.jsonly when your project needs fallback coverage (See: ESLint Fallback Quick Start)
Install
npm i -D oxlint oxfmt @bassist/oxc-integrationIf your project needs ESLint fallback, install the framework-specific ESLint packages too.
Editor Setup
oxlint / eslint CLI checks and editor diagnostics are not the same thing.
If you want in-editor Oxc lint feedback while coding, install an Oxc editor extension too. Otherwise you may only discover some issues when running the lint command in the terminal, even though the editor showed no warning.
- VS Code / Cursor: install the official
oxc.oxc-vscodeextension - Other editors: follow the official Oxc editor setup guide
See the official docs: https://oxc.rs/docs/guide/usage/linter/editors.html
Oxc editor extensions use oxlint --lsp from your project, so make sure
oxlint is installed locally in devDependencies.
If you use VS Code or Cursor, adding a workspace-level
.vscode/settings.json can make save actions and type-aware checks feel much
more complete:
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "always",
"source.fixAll.oxc": "always"
},
"oxc.typeAware": true
}source.fixAll.oxcenables Oxc fixes on save through theoxc.oxc-vscodeextensionoxc.typeAware: truehelps the extension provide type-aware diagnostics when your project uses TypeScript- Keep
source.fixAll.eslintif your project also useseslint.config.jsas a fallback layer - If your project is fully Oxlint-only, you can remove the ESLint save action
Positioning
- Use
@bassist/eslint-configwhen you want the current stable ESLint-first mainline. - Use
@bassist/oxc-integrationwhen you want an Oxc-first workflow package. - Treat this package as the transition path toward a future
@bassist/oxc-config.
How It Works
@bassist/oxc-integration uses an Oxc-first workflow:
oxlintis the primary lintereslintis the fallback linter for rules not fully covered by Oxc yetoxfmtis the primary formatter
This is why some projects still keep both oxlint.config.ts and eslint.config.js.
They are not two equal lint entrypoints anymore:
oxlint.config.tsis the main lint configeslint.config.jsis the fallback config
Inside the fallback presets, eslint-plugin-oxlint is applied to disable overlapping ESLint rules that Oxlint already covers.
When You Need ESLint Fallback
Use only oxlint.config.ts when Oxc already covers your project well enough.
Add eslint.config.js when your project still needs ecosystem-specific ESLint coverage.
In practice:
base/node: often Oxlint-only is enoughreact: Oxlint-first works well, but ESLint fallback is still useful in many projectsvue: keep ESLint fallback by defaultnext: keep ESLint fallback by defaulttailwindcss: add ESLint fallback when your project uses Tailwind CSS utility classesvitest: add ESLint fallback when you want test-specific rules beyond Oxlint
Built-in Fallback Coverage
Current built-in ESLint fallback presets provided by @bassist/oxc-integration:
javascripttypescriptjsximportsmarkdownreacttailwindcssvuenextvitest
Current out-of-scope area for this Oxc-first workflow:
lint-md- Prettier-based Markdown content workflows
These can be revisited later as a separate content-layer workflow.
Config Overview
| Project Type | oxlint.config.ts | eslint.config.js | oxfmt.config.ts |
|---|---|---|---|
| Base TS/JS | required | optional | required |
| Node | required | optional | required |
| React | required | recommended | required |
| Vue | required | recommended | required |
| Next | required | recommended | required |
Oxlint Quick Start
Base TS/JS
// oxlint.config.ts
import { defineOxlintConfig, oxlintPresets } from '@bassist/oxc-integration'
export default defineOxlintConfig(oxlintPresets.base())React
// oxlint.config.ts
import { defineOxlintConfig, oxlintPresets } from '@bassist/oxc-integration'
export default defineOxlintConfig(oxlintPresets.react(), oxlintPresets.vitest())Vue
// oxlint.config.ts
import { defineOxlintConfig, oxlintPresets } from '@bassist/oxc-integration'
export default defineOxlintConfig(oxlintPresets.vue(), oxlintPresets.vitest())If you need official oxlint types, import them directly from oxlint instead of from this package.
Built-in Oxlint Defaults
oxlintPresets.base() is not an empty shell. It already enables the shared Oxc baseline used by this package.
Current built-in defaults include:
- plugins:
typescript,oxc - categories:
correctness: errorsuspicious: errorpedantic: warnstyle: off
- base override:
typescript/no-explicit-any: off
Then higher-level presets extend that baseline:
oxlintPresets.node()adds Node runtime envoxlintPresets.react()addsreact,react-perf,jsx-a11yoxlintPresets.vue()addsvueoxlintPresets.vitest()addsvitest
Extending Oxlint Presets
Use the built-in defaults first, then pass extra config only for project-specific overrides.
// oxlint.config.ts
import { defineOxlintConfig, oxlintPresets } from '@bassist/oxc-integration'
export default defineOxlintConfig(oxlintPresets.react(), {
rules: {
'no-console': 'warn',
},
ignorePatterns: ['fixtures/**'],
})Think of the presets as the default baseline, and the extra object as the per-project extension layer.
ESLint Fallback Quick Start
Vue / Next / complex React projects
// eslint.config.js
import { defineEslintConfig, eslintPresets } from '@bassist/oxc-integration'
export default defineEslintConfig(
eslintPresets.imports(),
eslintPresets.react(),
eslintPresets.tailwindcss(),
eslintPresets.vitest(),
)For Vue projects, switch react() to vue().
For Next projects, use next().
Add tailwindcss() only when the project actually uses Tailwind CSS.
Markdown content linting
// eslint.config.js
import { defineEslintConfig, eslintPresets } from '@bassist/oxc-integration'
export default defineEslintConfig(eslintPresets.markdown())Use markdown() when you want standalone Markdown linting behavior without
pulling Markdown files into the lint-md or Prettier-based content workflow.
Oxfmt Quick Start
Prefer a typed oxfmt.config.ts file so the config shape stays aligned with the official formatter API.
// oxfmt.config.ts
import { defineConfig } from 'oxfmt'
import { oxfmtConfig } from '@bassist/oxc-integration'
export default defineConfig(oxfmtConfig)If you want to override the defaults:
// oxfmt.config.ts
import { defineConfig } from 'oxfmt'
import { getOxfmtConfig } from '@bassist/oxc-integration'
export default defineConfig(
getOxfmtConfig({
semi: true,
}),
)oxfmt . will automatically discover oxfmt.config.ts, so you usually do not need to pass a config path explicitly.
If you need official formatter types, import them directly from oxfmt instead of from this package.
Recommended Scripts
{
"scripts": {
"lint": "oxlint .",
"lint:eslint": "eslint .",
"lint:full": "npm run lint && npm run lint:eslint",
"format": "oxfmt ."
}
}Recommended usage:
- start with
lintforbase/node - use
lint:fullforvue,next, and more complexreactprojects