Skip to Content
Vektos
Guides

Lint

oxlint with type-aware and Panda-aware rules.

What

Linting runs on oxlint, with three layers of rules:

  • Built-in (correctness, suspicious, React, a11y, Next, imports).
  • Type-aware, through tsgolint, which is built on the same TypeScript 7 we use.
  • Panda-aware, through @pandacss/eslint-plugin, loaded as an oxlint JS plugin from oxlint-panda.mjs at the repo root.

Formatting is oxfmt. Both run in bun run check.

Why

Types stop a wrong value. The Panda rules explain it: "12px is not a token, the matching token is 3". They also catch mistakes that compile fine but produce no CSS, like ":hover" without &, which Panda ignores silently.

The same rules can later run on agent-generated code with JSON output, as one more grader that already knows the design system.

Try it

Create a file with deliberate mistakes:

// packages/ds/src/scratch.tsx
import { css } from "styled-system/css";
export const bad = css({
  bg: "#ff0000",
  color: "neutral.0",
  px: "12px",
  marginLeft: "2",
  ":hover": { bg: "accent.emphasized" },
});
bun run lint
error   prefer-token            Use a colors token instead of the hardcoded value "#ff0000".
error   no-primitive-token      Use a semantic colors token instead of the primitive token "neutral.0".
error   prefer-token            Hardcoded spacing value "12px". Matching tokens: 3.
warning no-physical-properties  Use the logical property "marginInlineStart" instead of "marginLeft".
error   no-invalid-nesting      Nested selector ":hover" has no "&", so Panda ignores it.

Delete the file afterwards. With the oxc VS Code extension (recommended in .vscode/extensions.json) the same messages appear inline while you type.

Two of those rules are about meaning, not syntax. prefer-token says "use a token". no-primitive-token says "use the semantic one": neutral.0 is a valid token, but a component should say accent.fg or bg.surface, so that it follows the theme. A value that is valid and still wrong is the kind of mistake the benchmark is built to count.

Extend it

  • Turn a rule on or off in .oxlintrc.json, under rules. Panda rules are prefixed @pandacss/. The full list is in the plugin README: node_modules/@pandacss/eslint-plugin/README.md.
  • no-primitive-token is configured for colors only: those are the tokens that have a semantic layer. Add a category to its categories when another one gets semantic tokens.
  • Widen prefer-token. It checks colors, spacing, fontSizes and radii today. Add a category to its categories array to cover more.
  • Lint another Panda config. The plugin binds one config per run. oxlint-panda.mjs sets cwd to packages/ds because Panda resolves its include globs from the working directory, not from the config path.
  • Auto-fix on save is configured in .vscode/settings.json (source.fixAll.oxc).

Known gaps

  • oxlint JS plugins are alpha. If a Panda rule misbehaves, check the plugin version before blaming the rule.
  • tsgolint is tied to the exact TypeScript version. Upgrade typescript and oxlint-tsgolint together.
  • The plugin declares eslint as a peer dependency. Bun installs it; nothing uses it.

On this page