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

webadwaita

v0.2.2

Published

Cross-platform Adwaita-styled UI components built on react-strict-dom.

Readme

WebAdwaita

Cross-platform React component library inspired by GNOME's libadwaita, built on react-strict-dom. One TypeScript codebase renders on web, iOS, and Android.

Why react-strict-dom?

react-strict-dom is Meta's strict subset of <html.*> primitives plus a css.create API that compiles to StyleX on web and React Native styles on native. WebAdwaita uses it so every component is platform-neutral by default — no .web.tsx / .native.tsx forks needed.

Components

| Component | Purpose | | --- | --- | | Box | Flex layout primitive (direction / gap / padding / align / justify). | | Button | Variants: default, suggested, destructive, flat, pill. Sizes: sm / md / lg. | | Entry | Text input with focus underline (Adwaita AdwEntry). | | Switch | Pill-shaped toggle with sliding thumb. | | Checkbox | Square checkbox with optional label. | | Card | Surface with optional title; boxed and flat variants. | | HeaderBar | Top bar with leading / centered title / trailing slots. |

Install

npm install webadwaita react-strict-dom

Peer deps: react ^19, plus react-dom (web) or react-native >= 0.79 (native).

Setup

WebAdwaita ships precompiled JS plus per-component CSS — no special bundler config required. Install, import, render:

npm install webadwaita react-strict-dom
import { Button, Card } from 'webadwaita';

That's it. Each component side-effect-imports its own CSS chunk, so your bundler ships only the styles for the components you actually use (works in Next.js, Vite, CRA, anywhere with a modern bundler honoring package.json#sideEffects).

Native (Expo / Metro): the package's react-native exports condition routes Metro to a precompiled native build that uses RN StyleSheet at runtime. No Babel preset to wire up in your app — just import { Button } from 'webadwaita'.

How the build works

The library has a build step (npm run build) that produces:

dist/
  web/<Component>/index.js          ← starts with `import './styles.css'`
  web/<Component>/styles.css        ← only that component's atomic rules
  web/_tokens/styles.css            ← shared baseline (loaded once)
  native/<Component>/index.js       ← RN StyleSheet output, no CSS
  types/<Component>/index.d.ts

Two design-token notes carry over to consumer code:

  • Tokens still live in src/tokens.css.ts. The .css.ts filename is required: react-strict-dom's StyleX config treats .css as the token-file extension, so any file calling css.defineConsts / css.defineVars must follow that convention.
  • src/theme.ts re-exports the same tokens for runtime use.

Use

import { Box, Button, Card, Entry, Switch } from 'webadwaita';

export function Settings() {
  const [name, setName] = useState('');
  const [enabled, setEnabled] = useState(true);

  return (
    <Card title="Profile">
      <Box gap="md">
        <Entry placeholder="Your name" value={name} onChange={setName} />
        <Box direction="row" align="center" gap="sm">
          <Switch checked={enabled} onChange={setEnabled} />
          <span>Enabled</span>
        </Box>
        <Button variant="suggested">Save</Button>
      </Box>
    </Card>
  );
}

Develop

# library
npm install
npm run build       # produces dist/{web,native,types}
npm run typecheck

# web Storybook (Vite-powered)
npm --prefix apps/storybook-web install
npm run storybook:web                # opens http://localhost:6006

# native Storybook (Expo + @storybook/react-native v8, on-device UI)
npm --prefix apps/storybook-native install
npm run storybook:native             # then press i / a / w in the Expo CLI

The native app embeds the Storybook UI directly — open the Expo Go app on a phone (or a simulator) and pick a component from the on-device sidebar. After adding/removing .stories.tsx files, regenerate the registry:

npm --prefix apps/storybook-native run storybook-generate

License

MIT — see LICENSE. Inspired by react-strict-dom's apps/example-ui/ and the libadwaita design system.