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

@snapt/ui

v0.2.0

Published

Snapt's design system: tokens, Tailwind theme and React components.

Readme

@snapt/ui

Snapt's design system: tokens (colors, type, radii, shadows) and the React components every Snapt app is built from, published on npm as @snapt/ui.

npm install @snapt/ui
import { Button } from "@snapt/ui/components/Button";
import { PageHeader } from "@snapt/ui/components/PageHeader";
import { AppLayout } from "@snapt/ui/components/AppLayout";
import { colors } from "@snapt/ui/tokens";

It ships compiled ESM + type declarations (dist/), with react (18 or 19) as a peer dependency and lucide-react for icons — no transpilePackages needed. Browse everything in Storybook: npm run storybook.

What's in it

| Import | What | | --- | --- | | @snapt/ui/tokens | Token values in TS: colors, fonts, radii, shadows | | @snapt/ui/theme.css | The tokens as CSS variables (--snapt-color-bg, …) + base page styles | | @snapt/ui/tailwind.css | Tailwind v4 theme mapping utilities onto the variables | | @snapt/ui/tailwind-preset | The same mapping as a Tailwind v3 preset | | @snapt/ui/components/* | AppLayout, BrandMark, Logo (SnaptLogo, SnaptMark), Nav (NavGroup, NavItem, BottomNav…), PageHeader, Button, button-styles, Card, StatCard, Badge, Avatar, ProgressBar, Field (Input, Select, Textarea), SegmentedControl, Sheet, EmptyState |

The look lives in src/tokens.ts only. Components use utility names (bg-panel, text-muted, rounded-lg, font-mono…) that resolve to the CSS variables, so changing a token restyles every app.

Setup in an app

Tailwind v4 — in the global CSS:

@import "tailwindcss";
@import "@snapt/ui/tailwind.css"; /* theme + variables, and scans the components */

Tailwind v3 — in tailwind.config.ts:

import snaptPreset from "@snapt/ui/tailwind-preset";

export default {
  presets: [snaptPreset],
  content: ["./src/**/*.{ts,tsx}", "./node_modules/@snapt/ui/dist/**/*.js"],
};

and import @snapt/ui/theme.css once (e.g. in the root layout).

Fonts. The look follows snapt.tech: Inter, light weights for large headings, tabular numerals for figures. Load Inter in the app; with next/font, point the variable at the generated family:

const inter = Inter({ subsets: ["latin"], variable: "--font-sans" });
:root {
  --snapt-font-sans: var(--font-sans), system-ui, sans-serif;
}

Links and routers

next (or any router) is deliberately not a dependency: a component built against a different copy of next than the app's own would silently fail to navigate. Components that render links take the app's link component instead:

import Link from "next/link";
<NavItem as={Link} href="/cantieri" icon="site" label="Cantieri" active />

For a link styled as a button, wrap your own Link around buttonClassName():

import Link from "next/link";
import { buttonClassName } from "@snapt/ui/components/button-styles";

<Link href="/sign-in" className={buttonClassName("secondary", "lg")}>Accedi</Link>

Icons are Lucide: import them from lucide-react in the app and pass elements — icon={<Building2 />}. Components size them; a <Button> sizes any <svg> inside it.

Interactive components (SegmentedControl, Sheet) carry "use client"; the rest render on the server.

Developing and releasing

npm install
npm run build          # tsc → dist/, then tokens → dist/theme.css, dist/tailwind.css
npm run typecheck
npm run storybook      # http://localhost:6006

Every component gets a story in stories/. CI typechecks, builds the package and builds Storybook on every push and pull request.

To release: bump version in package.json (semver: a changed class or prop is a breaking change for apps), merge to main, then push a matching tag — git tag v0.2.0 && git push origin v0.2.0. The Publish workflow typechecks, builds and publishes it through npm trusted publishing (no token). This repo is private, so npm doesn't attach a provenance attestation. Apps pick it up by bumping their dependency.

Try a change in an app before releasing: npm pack here, then npm install --no-save ../path/to/snapt-ui-<version>.tgz in the app.