Skip to main content

@yummacss/lint

Lint rules for Oxlint, and a one-off check with yummacss lint.

Optional

Yumma CSS generates the same CSS with or without it. Reach for it when you want the check, not to get started.

Every Yumma CSS class names a value from a table, so whether a class exists is a yes or no question. The lint rules ask it in your editor and in CI, and answer with the class you meant.

They read your yumma.config.mjs, so variants, opacity modifiers, negative values, CSS functions, your own colors & states, & safelist entries all pass.

Oxlint

  1. 1

    Install the Plugin

    pnpm add -D oxlint @yummacss/lint
    
  2. 2

    Turn On the Rules

    Register the plugin & pick a level for each rule.

    .oxlintrc.json
    {
      "jsPlugins": ["@yummacss/lint"],
      "rules": {
        "yummacss/no-unknown-classes": "error",
        "yummacss/no-inline-styles": "warn"
      }
    }
    
  3. 3

    Run It

    pnpm oxlint
    
    src/app.tsx:4:25: error yummacss(no-unknown-classes): `bg:redd-5` is not a Yumma CSS class, so it generates no CSS. Did you mean `bg:red-5`?
    src/app.tsx:4:68: warning yummacss(no-inline-styles): `display: flex` is set inline. Use `d:f` instead.
    

The plugin is written in the ESLint plugin format, which is the format Oxlint loads, so ESLint runs it too.

Rules

RuleReports
no-unknown-classesA class Yumma CSS does not generate, such as bg:redd-5, with the closest class that exists.
no-inline-stylesA property in a style object, with the class that writes the same declaration, such as d:f for display: "flex".

Both rules read className & class, and the arguments of cn, cx, clsx, classNames & merge from yummacss/merge. Ternaries, arrays, object keys & the static parts of a template literal are all read.

no-inline-styles skips custom properties, so a value that changes at runtime goes through one:

<div className="w:var(--progress)" style={{ "--progress": `${value}%` }} />

Runtime classes are invisible

A class assembled at runtime cannot be checked. In className={`p:4 ${size}`} the p:4 is checked & ${size} is skipped.

Options

Every rule takes allow & message.

.oxlintrc.json
{
  "rules": {
    "yummacss/no-unknown-classes": ["error", {
      "allow": ["brand-logo", "editor-*"],
      "message": "{{className}} is not on the scale. Did you mean {{suggestions}}?"
    }]
  }
}
OptionTypeDescription
allowstring[]Class names to accept, or CSS property names for no-inline-styles. A trailing * matches a prefix.
messagestringReplaces the rule's message. {{className}}, {{property}} & {{suggestions}} are filled in.

Skip a single line with a comment:

// oxlint-disable-next-line yummacss/no-unknown-classes
<div className="brand-logo" />

One-Off Check

yummacss lint scans the source files from your config & lists every class it does not recognize, with no linter to set up.

pnpm dlx yummacss lint
Scanned 128 files and found 214 unique classes.
Found 2 classes Yumma CSS does not recognize:
 "ai:st" - did you mean "ai:s"?
  - src/components/hero.tsx
 "flex-center"
  - src/components/layout.tsx
Fix the classes above, or pass --allow "class-a,class-b" for custom classes.

It exits with 1 when it finds a class it does not recognize, so it works as a CI step on its own.

FlagAliasDescription
--allow-aComma-separated class names to skip. Repeat it to add more.
--config-cPath to the config file, absolute or relative to the working directory. Defaults to yumma.config.mjs.

It reads class attributes & the first string passed to cn, clsx, classnames & cva. The Oxlint rules read more, so prefer them in a project that lints already.