Oxlint plugin
Lint Ilha components for primitive placement, generator instructions, and event props that TypeScript cannot check.
TypeScript types your props and atoms. It cannot see call order, generator frames, or React-shaped event names. The Oxlint plugin flags those mistakes in the editor and in CI.
The plugin ships as @ilha/router/oxlint. It is a JavaScript Oxlint plugin — no extra compiler.
Install
Install Oxlint and @ilha/router if the app does not already depend on the router.
npm install -D oxlint @ilha/routerpnpm add -D oxlint @ilha/routeryarn add -D oxlint @ilha/routerbun add -D oxlint @ilha/routernub add -D oxlint @ilha/routeraube add -D oxlint @ilha/routerEnable the plugin
Point Oxlint at the export and turn on the rules you want.
{
"jsPlugins": ["@ilha/router/oxlint"],
"rules": {
"oxlint-plugin-ilha/no-conditional-primitive": "error",
"oxlint-plugin-ilha/no-primitive-outside-component": "error",
"oxlint-plugin-ilha/no-instruction-outside-generator": "error",
"oxlint-plugin-ilha/prefer-lowercase-events": "error",
"oxlint-plugin-ilha/function-in-atom": "error"
}
}
Save this as .oxlintrc.json at the repo root. Run oxlint in your lint script.
The plugin only treats atom, watch, and when as primitives when you import them from "ilha". A router action() or a local binding does not match.
Rules
| Rule | Catches |
|---|---|
no-conditional-primitive |
atom() / watch() / when() inside if or a loop |
no-primitive-outside-component |
Primitive calls at module top level — there is no fiber there |
no-instruction-outside-generator |
when outside a generator, or without yield* |
prefer-lowercase-events |
onClick instead of onclick |
function-in-atom |
atom(fn) misread as a derived initializer instead of a stored function — use atom(Atom.map(...)), atom(Atom.transform(...)), or atom.lazy(() => fn) |