Skip to content
Ilha
Esc
↑↓navigate↵open⌘Jpreview
On this page

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/router
pnpm add -D oxlint @ilha/router
yarn add -D oxlint @ilha/router
bun add -D oxlint @ilha/router
nub add -D oxlint @ilha/router
aube add -D oxlint @ilha/router

Enable 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)

Was this page helpful?