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

@sub-design/ui

v0.26.0

Published

Portable React controls for GoodSync and NOKL. Twenty families today: Badge, Button, Card, Checkbox, Context Menu, Dialog, Input, Label, Menu, Notice, Radio Group, Select, Separator, Sheet, Skeleton, Status Mark, Switch, Tabs, Textarea, Tooltip.

Readme

@sub-design/ui

Portable React controls for GoodSync and NOKL. Twenty families today: Badge, Button, Card, Checkbox, Context Menu, Dialog, Input, Label, Menu, Notice, Radio Group, Select, Separator, Sheet, Skeleton, Status Mark, Switch, Tabs, Textarea, Tooltip.

What makes a component belong here

Core UI owns portable controls and accessible interaction patterns. File rows, filter bars, sortable admin tables and marketing sections are not core primitives — see docs/adr-0001-platform-foundation.md.

Two independent consumers is the bar, and it is necessary rather than sufficient — Card's own history is the cautionary tale for how to apply it. It was rejected once as unshareable because its two implementations shared a name and nothing else; promoted later, 2026-08-11, once the same comparison was redone property by property instead of as a totalled judgment. Notice/Alert followed the same day: two real consumers whose colours already converged, blocked instead by a composition-model difference — prop slots vs. a compound component — that no token could carry, resolved by adopting Enterprise's compound shape and adding the action slot it lacked. See docs/roadmap.md's Delivery 3 section for both.

The complete promotion and API-evolution rules live in docs/evolution-policy.md.

Installing

npm install @sub-design/ui @sub-design/tokens @sub-design/themes

@base-ui/react, react and react-dom are peers.

The package ships source, not a build: .tsx files that a consumer's own bundler compiles. That keeps one React instance and lets each product's Tailwind generate only the classes it uses — but it means the classes are invisible to Tailwind unless each adopted file is scanned explicitly:

@import "@sub-design/tokens";
@import "@sub-design/themes/goodsync";

@source "../node_modules/@sub-design/ui/src/button.tsx";

Add a @source line per component adopted. Without it the component renders unstyled, and nothing warns.

How it stays brand-neutral

Every class resolves through a token. No component contains a palette value, a radius literal, or a product name — swapping data-brand is the only thing that changes how it looks. Colours use the (color:--token) form and lengths (length:--token), because Tailwind cannot otherwise tell what a bare custom property holds.

Base UI is the primitive engine and stays behind this package; products import from here, never from @base-ui/react, so the engine can be replaced without touching product code.

Accessibility

Focus geometry, pointer target sizes and contrast are treated as guarantees rather than style. --focus-ring-width and --switch-hit-area-min live in the token contract for that reason, and a product that redeclares them silently changes adopted components too.

Theme contrast is asserted in test/contrast.test.ts — eight pairs across both brands and both colour schemes, read from the real CSS. Three GoodSync values shipped below AA before it existed.