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

@duro-app/eslint-plugin

v2.0.1

Published

ESLint rules enforcing the Duro design system conventions: react-strict-dom html.* elements, deep token imports, token values over raw px/hex, and no deprecated Table parts.

Readme

@duro-app/eslint-plugin

ESLint rules that enforce the Duro design system conventions mechanically — what CLAUDE.md can only suggest, these rules gate.

Requires ESLint 9 (flat config). The plugin has zero runtime dependencies.

Usage

// eslint.config.js
import duro from '@duro-app/eslint-plugin'
import tseslint from 'typescript-eslint'

export default [
  ...tseslint.configs.recommended,
  duro.configs.recommended,
  {
    rules: {
      // Example: a data grid the design system doesn't cover yet.
      'duro/no-raw-html-element': ['error', {allow: ['table', 'thead', 'tbody', 'tr', 'th', 'td']}],
    },
  },
]

The recommended preset registers the plugin under the duro namespace, so you never have to register it yourself. Don't also register it manually under another key — you'd get two live namespaces and confusing config.

Rules

| Rule | Preset | Fix | | -------------------------------- | ------ | -------------------- | | duro/no-raw-html-element | error | suggestion | | duro/no-tokens-barrel-import | error | autofix | | duro/no-deprecated-table-parts | error | autofix / suggestion | | duro/no-raw-design-values | warn | suggestion |

no-raw-html-element

Raw lowercase JSX intrinsics (<div>, <span>, …) must be react-strict-dom html.* elements. SVG subtrees are exempt (RSD has no SVG primitives). Elements RSD doesn't export (<table>, <canvas>, …) report as non-portable; allow them explicitly per-project via allow. The rewrite is a suggestion, not an autofix, because html.* props are stricter than raw DOM props — a mechanical --fix would trade lint errors for type errors.

Options: {allow?: string[], reportUnsupported?: boolean, htmlModule?: string}

no-tokens-barrel-import

import {colors} from '@duro-app/tokens' breaks the StyleX babel plugin. The autofix splits the barrel import into the right deep imports (@duro-app/tokens/tokens/colors.css, …), preserving aliases and inline type specifiers. Imports with any unmapped specifier report without a fix.

Options: {packages?: string[]}

no-deprecated-table-parts

Flags <Table.Container> (Root owns the container query now; report-only — unwrapping is layout-unsafe to automate) and the no-op isActions prop on <Table.HeaderCell> (autofixed away for literal values; suggestion when the value is an expression). Matches by identifier name (Table, TableCore by default) — configure via tableIdentifiers.

no-raw-design-values

Inside css.create() objects: hex colors report everywhere (palette matches suggest the colors.* token; off-palette hexes report without a fix), and numeric/px values matching the spacing or radius scale report on the properties where that mapping is unambiguous (padding/margin/gap families → spacing.*, border radius family → radii.*). width: 16 or fontSize: 16 never report — same number, different meaning. Ships as warn: it informs, it doesn't gate.

Options: {factories?: string[], spacingProperties?: string[], radiiProperties?: string[]} (property lists replace the defaults, they don't merge)

Token data

The rule data (deep-path map, spacing/radius px values, color palette) is mirrored from @duro-app/tokens as literals so the published plugin stays dependency-free. test/token-drift.test.ts rebuilds every table from the real tokens package and fails CI when they drift.