Oxlint Plugin
oxlint-plugin-vize lets Oxlint execute Vize Patina diagnostics through Oxlint's JS plugin system.
Use it when you want Oxlint's Rust-native JS and TS rules together with Vize's Vue-aware
diagnostics in one run.
For the native lint and type-checking pipeline outside Oxlint, see Static Analysis.
Important
The package is available on npm, but the integration is still early. For human-readable terminal output, prefer
oxlint-vize -f stylishwhile original SFC range fidelity continues to improve.
Installation
Install vp once from the Vite+ install guide, then add the packages:
vp install -D oxlint oxlint-plugin-vize
oxlint-plugin-vize resolves the matching Vize native binding through optional dependencies, so
most users do not need to install @vizejs/native separately.
Which File To Configure
| Command | Reads |
|---|---|
vp lint, vp check |
the lint block in vite.config.ts |
oxlint, oxlint-vize |
.oxlintrc.json (or -c <path>) |
Warning
Vite+ never reads
.oxlintrc.json. A.oxlintrc.jsoncarryingjsPluginsandvize/*rules looks configured, butvp lintignores the file, so Oxlint never sees avize/*rule id and reports zero Vize diagnostics while exiting0.vp lint --initdoes not migrate an existing.oxlintrc.jsoneither: it writes a freshlintblock and leaves the old file in place.
vize init picks the right file for you: it detects whether your lint command is
vp lint or oxlint and writes the configuration that command reads, or writes both when both are
in use. It also refuses to write anything rather than fall back to a file your lint command ignores.
Basic Usage With vp lint
createVizeLintConfig() returns a complete Vite+ lint block, so the jsPlugins entry that loads
the bridge cannot go missing. The default preset is "happy-path"/"general-recommended": use it
when you want a safe Vue baseline without taking a position on stronger style or framework choices.
// vite.config.ts
import { defineConfig } from "vite-plus";
import { createVizeLintConfig } from "oxlint-plugin-vize";
export default defineConfig({
lint: createVizeLintConfig({
preset: "happy-path",
rules: {
"no-console": "warn",
},
settings: {
helpLevel: "short",
},
}),
});
preset drives both the emitted rule map and settings.vize.preset when a single bundle is
selected. Keeping them in lockstep matters because the bridge silently drops any vize/* rule
outside the active preset, so a rule listed under a mismatched preset reports nothing at all.
createVizeLintConfig throws for that case, and for unknown vize/* ids, rather than leaving you
with a config that looks enabled and stays silent.
preset: "incremental"runs only the rules you list.preset: ["happy-path", "ecosystem"]orpresets: ["happy-path", "ecosystem"]unions multiple bundles. The helper emitssettings.vize.preset: "incremental"for those configs so the runtime gate cannot suppress one bundle's rules while another bundle is active.preset: "all"runs every bundle at once.pluginskeeps the rest of your built-in Oxlint plugins. They are merged withvue, never replaced, because narrowing the list would silently drop everything those plugins report. Acreate-vueproject passes["eslint", "typescript", "unicorn", "oxc"].- Spread the result (
{ ...createVizeLintConfig(), ignorePatterns: ["dist/**"] }) to merge it into an existinglintblock.
For Flat Config-style composition in vite.config.ts, use spreadable fragments and collapse them
back to Vite+'s object-shaped lint config:
// vite.config.ts
import { defineConfig } from "vite-plus";
import { defineVizeLintConfig, flatConfigs } from "oxlint-plugin-vize";
export default defineConfig({
lint: defineVizeLintConfig(
...flatConfigs.recommended,
...flatConfigs.ecosystem,
{
ignorePatterns: ["dist/**"],
rules: {
"no-console": "warn",
},
},
),
});
The exported fragments include flatConfigs.recommended, flatConfigs.happyPath,
flatConfigs.essential, flatConfigs.ecosystem, flatConfigs.nuxt, flatConfigs.opinionated,
and flatConfigs.all, plus the same *WithTypeAware variants as configs.
Basic Usage With oxlint And oxlint-vize
{
"plugins": ["vue"],
"jsPlugins": ["oxlint-plugin-vize"],
"settings": {
"vize": {
"helpLevel": "short"
}
},
"rules": {
"eqeqeq": "error",
"vize/vue/require-v-for-key": "error",
"vize/vue/no-v-html": "warn",
"no-console": "warn"
}
}
If you use a JS or TS Oxlint config, the package also exports preset rule maps:
import { configs } from "oxlint-plugin-vize";
export default {
plugins: ["vue"],
jsPlugins: ["oxlint-plugin-vize"],
settings: {
vize: {
helpLevel: "short",
preset: "opinionated",
typeAware: true,
},
},
rules: configs.opinionatedWithTypeAware,
};
Available preset exports include:
configs.recommendedconfigs.happyPathconfigs.essentialconfigs.opinionatedconfigs.nuxtconfigs.allconfigs.recommendedWithTypeAwareconfigs.happyPathWithTypeAwareconfigs.ecosystemWithTypeAwareconfigs.opinionatedWithTypeAware
Recommended Command
vp exec oxlint-vize -c .oxlintrc.json -f stylish src
oxlint-vize is a thin wrapper around oxlint that smooths over scriptless .vue edge cases
while upstream JS plugin coverage continues improving.
Settings
Settings are passed through settings.vize:
{
"settings": {
"vize": {
"locale": "ja",
"preset": "general-recommended",
"helpLevel": "short",
"typeAware": true
}
}
}
localecontrols the diagnostic language.presetaccepts"general-recommended"/"happy-path","essential","ecosystem","incremental","opinionated","nuxt", or"all".presetdefaults to"general-recommended".incrementalruns only the rules you explicitly configure.allis accepted as a settings alias forincremental; useconfigs.allorcreateVizeLintConfig({ preset: "all" })when you also want every rule emitted.helpLevelaccepts"full","short", or"none".typeAware: trueenables Corsa-backedvize/type/*rules during shared Patina passes.corsaPathselects the Corsa ortsgoexecutable for type-aware linting.showHelpandsettings.patinaare still accepted for backward compatibility.
Current Limitations
- Raw
oxlintcan still miss some.vuefiles without<script>or<script setup>. Useoxlint-vizeif your project includes template-only SFCs. - Oxlint JS plugins still anchor ranges to the extracted script program, so template and style diagnostics do not yet preserve original SFC ranges in every formatter.
stylishis currently the best human-readable formatter for mixed Oxlint + Vize output. JSON and other machine-readable formats should be treated as best-effort for original template/style positions.- Type-aware rule exports are experimental. Use a
*WithTypeAwareconfig and setsettings.vize.typeAware: truewhen you want the shared full-file pass to run those rules eagerly.
Local Development
nix develop
vp install --frozen-lockfile
vp run --filter './npm/native' build
vp run --filter './npm/oxlint' build