npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@omit-design/eslint-plugin

v0.3.0

Published

Hard rules for omit-design business pages: no design literals, whitelist imports, mandatory pattern header, pattern-scoped component requirements.

Readme

@omit-design/eslint-plugin

Four hard rules for omit-design business pages. Where AI-collaborative design correctness gets enforced.

npm License: MIT

These four rules are the enforcement boundary for AI-collaborative design composition. They keep design files predictable enough that an agent (or a human reviewer) can read, edit, and reason about them without surprises.

Rules

| Rule | Forbids | Use instead | |---|---|---| | omit-design/no-design-literal | Raw colors / sizes / spacing in design files | var(--om-*) tokens | | omit-design/whitelist-ds-import | Imports outside the design-system whitelist | @omit-design/preset-mobile (Om* components) + a few layout-only Ionic components | | omit-design/require-pattern-header | Files without a // @pattern: <name> first-line comment | Add the header; <name> must exist in PATTERNS.md | | omit-design/require-pattern-components | Files declaring @pattern: X but importing none of X's signature components | Import at least one of the pattern's signature components per patterns.config.json |

Example violations

// ❌ no-design-literal
<div style={{ color: "#FF6B00", padding: "12px" }} />
//          ↑ literal hex          ↑ literal px

// ❌ whitelist-ds-import
import { IonButton } from "@ionic/react";
//       ↑ outside whitelist; use OmButton from @omit-design/preset-mobile

// ❌ require-pattern-header
import { OmPage } from "@omit-design/preset-mobile";  // ← file's first line
//   ↑ missing `// @pattern: <name>` above this line

// ❌ require-pattern-components
// @pattern: list-view
import { OmCard, OmPage } from "@omit-design/preset-mobile";
//       ↑ list-view requires OmListRow / OmCouponCard / OmSettingRow /
//         OmProductCard / OmMenuCard / OmEmptyState — none imported.
// ✅ all four rules pass
// @pattern: detail-view
import { OmCard, OmHeader, OmPage } from "@omit-design/preset-mobile";
//       ↑ OmCard is the signature component for detail-view (per patterns.config.json)

export default function OrderDetail() {
  return (
    <OmPage padding="none" header={<OmHeader title="Order" />}>
      <OmCard>
        <span style={{ color: "var(--om-color-text)", padding: "var(--om-spacing-md)" }}>
          ¥58
        </span>
      </OmCard>
    </OmPage>
  );
}

Install

npm install -D @omit-design/eslint-plugin eslint

Usage (flat config)

// eslint.config.js
import omit from "@omit-design/eslint-plugin";

export default [
  {
    // The four hard rules ONLY apply to design files.
    // Don't enforce them on app shell / mock data / preset overrides.
    files: ["design/**/*.tsx"],
    plugins: { "omit-design": omit },
    rules: {
      "omit-design/no-design-literal": "error",
      "omit-design/whitelist-ds-import": [
        "error",
        { presets: ["@omit-design/preset-mobile"] },
      ],
      "omit-design/require-pattern-header": "error",
      "omit-design/require-pattern-components": "error",
    },
  },
];

Projects scaffolded by @omit-design/cli init already include this config — and a husky pre-commit hook so the same check runs on every git commit.

Configuration

whitelist-ds-import

{
  presets: ["@omit-design/preset-mobile"],   // declared design-system entries
  // Ionic exceptions (layout / icon hosts only)
  allowedIonic: ["IonList", "IonBackButton", "IonIcon"],
}

To add another preset (e.g. @omit-design/preset-desktop once it lands), just append to presets.

no-design-literal

Detects hex colors, RGB/RGBA strings, and pixel values inside JSX style={...} props and CSS-in-JS template literals. Allows:

  • Numbers in non-style contexts (<div data-x={12}>)
  • 0, auto, inherit, currentColor
  • Anything inside var(--om-*) (tokens are by design)
  • Test files (configurable via overrides)

require-pattern-header

Looks for the first non-blank line. If it's not // @pattern: <name>, error. The plugin doesn't validate <name> against any registry — that's the next rule's job.

require-pattern-components

Reads the @pattern: X header, then loads patterns.config.json (defaults to node_modules/@omit-design/preset-mobile/patterns.config.json) to get X's "signature components" — the components without which the file cannot meaningfully be that pattern. Errors if the file imports none of them.

{
  configPath: "node_modules/@omit-design/preset-mobile/patterns.config.json",  // default
}

The config file shape:

{
  "patterns": {
    "list-view": ["OmListRow", "OmCouponCard", "OmSettingRow", "OmProductCard", "OmMenuCard", "OmEmptyState"],
    "form-view": ["OmInput", "OmSelect", "OmNumpad"],
    "...": "..."
  }
}

Stops AI from declaring @pattern: list-view and writing a single OmCard. Custom presets can ship their own patterns.config.json and point the rule at it.

If the file's pattern name isn't in the config → reports unknownPattern (caller likely typo'd the pattern name). If the config file isn't found → reports configMissing (preset-mobile likely outdated; bump it).

Why hard rules?

Soft conventions ("please use tokens", "we generally avoid …") fail under AI generation. The model writes plausible-looking code that violates the convention silently, and review-burden creeps up. Hard rules turn the convention into a deterministic gate: npm run lint exits non-zero, the agent loops, the violation gets fixed before review.

License

MIT