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

@corndev/eslint-plugin

v1.0.0-beta.4

Published

Corn UI lint rules: props a component does not read, and values outside the ones it accepts

Readme

@corndev/eslint-plugin

Lint rules for code that uses Corn UI's React components. They catch the two mistakes a CSS-first library cannot report for itself, because CSS never errors:

  • a prop the component does not read, from another library's vocabulary — w={260}, mt="md", data={…} on a native Select. React passes it to the DOM as a stray attribute, or the component ignores it, and nothing says so.
  • a value outside the set a prop accepts — size="xs" on a component whose sizes start at sm. No stylesheet rule matches it, so it renders as the default size, which looks fine and is simply wrong.

Both were found the hard way by a real migration off Mantine: the first run of the check these rules grew from found three live bugs, and its first run against this repository found thirty-three buttons in the documentation's own examples rendering in the wrong colour.

Install

npm install --save-dev @corndev/eslint-plugin

It needs ESLint 8.57 or later, and Corn UI React packages at the same version as the plugin.

Use

With a flat config (eslint.config.js, the default from ESLint 9):

import corn from '@corndev/eslint-plugin';

export default [
  corn.configs.recommended,
];

With .eslintrc:

{
  "extends": ["plugin:@corndev/recommended-legacy"]
}

Rules

All four are in recommended.

@corndev/no-foreign-props

Reports a prop from another library's vocabulary on a Corn UI component that does not declare it. The list is Mantine's — the props a migration most often carries over by habit: spacing and sizing shorthands (m, mt, p, w, h, miw, …), style props (c, fw, fz, bg, …), and component props such as data, searchable, leftSection, styles and classNames.

A prop on the list is fine wherever a component really reads it: label on a Tab, clearable on a Combobox, leftSection on an Input. The rule checks each one against that component's declared props, so it only speaks up where the prop would go nowhere.

Options:

'@corndev/no-foreign-props': ['error', {
  props: ['sx'],   // more to flag
  allow: ['color'], // never flag these
}]

@corndev/prop-values

Reports a literal value outside the set a prop accepts:

<Button size="xs" />          // sm | md | lg
<Button variant="ghost" />    // button | icon | unstyled — the colour is `level`

It reads "x", {'x'} and {`x`}. A value computed at run time is left alone: the rule reports what it can prove, never a guess.

It also reports a literal object, array or string passed to a prop typed as a number:

<SimpleGrid cols={{ base: 1, sm: 3 }} />   // Mantine's responsive form

That becomes the string "[object Object]", and the grid silently falls back to one column.

@corndev/no-shadowed-props

Reports a data-* attribute that stands in for a prop the component has:

<Button data-emphasis="quiet" />   // use emphasis="quiet"

The component writes data-emphasis itself from its emphasis prop, and an attribute you pass lands after it — so yours silently wins, and the prop stops working without a sound. Markup written before a prop existed is where these come from: one app found 287.

@corndev/no-unbraced-expression

Reports JSX text that is an expression which lost its braces:

<MenuItem>
  target.shared ?
  <Shared /> : <Private />
</MenuItem>

This compiles, and prints "target.shared ?" beside both elements. It is what moving leftSection={x ? <A /> : <B />} into children produces when the braces do not come along — one app shipped it for weeks. The rule checks every element, not only Corn UI's, and stays quiet on prose: it reports text ending in &&, ||, or ? with a space before it (as a ternary is written, and an English question is not), and only when an element or {…} follows.

How it knows

Every Corn UI React package ships a props.json listing each component's props and the values of those with a fixed set. It is generated from the same JSDoc as the package's TypeScript declarations and its documentation, so the three cannot disagree, and the rules read the copy installed next to the file being linted — so they always describe the version you are actually using. If an installed version predates the manifest, the rules say so once per file instead of passing silently.

In a monorepo that lints source it has not built, point the rules at a manifest directly:

settings: {
  corndev: { manifests: { '@corndev/ui-react': manifestObject } },
}

Documentation

License

MIT