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

@sableui/react

v0.21.0

Published

Sable: themeable React components, layout patterns, and tools for coding agents.

Readme

Sable

Sable — a themeable React component system with layout patterns, semantic tokens and tools for coding agents. Default theme: Sable. On npm as @sableui/react; docs and the live catalog at sableui.com.

For a clickable iOS prototype (demos and presentations, not production), ask the Sable skill to build with the iOS target. Every screen is Sable components in your preset; the optional @sableui/react/ios adapter adds only the iOS system chrome (status bar, navigation bar, tab bar, sheet presentation), drawn by the optional konsta peer that the agent installs for that target. The prototype's document imports Tailwind, Sable's styles, a preset, then @sableui/react/ios/styles.css. Frame it with PhoneFrame from @sableui/react/ios/preview. See building an iOS prototype.

Original Sable code is MIT licensed.

The featured presets are Sable (neutral), Meridian (square), Prism (compact technical), Verdant (serif), Ember (warm), and Poppy (playful). Every preset supports light and dark modes. Load its declared fonts and use ThemeSelector to offer preset choices. Third-party notices list the software and fonts used in Sable.

  • Behavior: Base UI (@base-ui/react) — accessible primitives, isolated behind our own component APIs.
  • Styling: Tailwind CSS v4 + semantic CSS-variable tokens; variants via class-variance-authority.
  • Icons: opt-in through IconProvider — Reicon's set ships ready to mount, or plug in any icon package. Apps pay only for the set they choose.
  • Motion: a token-driven, zero-dependency motion layer (recipes, policy, browser-native primitives).
  • Themeable: components reference semantic tokens only; a theme is a CSS variable set.

A broad product component catalog, a fluid layout foundation, and a pluggable icon adapter — see registry.json.

Colour

Components paint roles (bg-card, bg-primary, text-muted-foreground), so a theme restyles everything at once. For colour beyond the roles, every theme also generates a palette: neutral, red, orange, yellow, green, teal, blue, purple and pink (50–950), plus a scale under every tone. The families lean toward the theme's brand, neutral is the theme's own page-to-ink ramp, and steps follow the mode, so bg-blue-100 text-blue-800 reads in light and dark. Use it for tags, avatars, labels and illustration; Badge, Pill and StatusDot take a family as their tone (<Badge tone="teal">). Tailwind's other colour families are switched off. See DESIGN.md → Generated palette.

Taste, style, and variety

A project can keep its own visual atlas at .sable/atlas/atlas.json: annotated desktop, mobile and interaction captures with conditional transfer principles and cautions. sable atlas --search retrieves contextual examples from it and --show returns verified local image paths, which an agent must actually view. The package ships no atlas; without one, work from the brief and the user's references.

When alternatives materially affect the brief, keep content and behavior fixed while rendering bounded directions with meaningful differences in composition, typography, density, imagery, story, or purposeful motion. sable explore --check design/directions.json checks the specification and capture hashes; --compare creates an offline comparison with anonymous labels and an explicit choice or tie. It exports a review record for sable prefer --record. Preferences live in the consuming project's .sable/preferences/, are scoped to a project, brand, person, or task, and distinguish an actual human judgment from an agent observation. Human-only retrieval is the default. These tools do not update model weights. See sable docs developing-taste for the complete workflow.

Install & setup

Agents: the machine-readable version of these steps is the consume block in registry.json.

Quick start — install, then let sable init do steps 2–5:

pnpm add @sableui/react
pnpm exec sable init        # or: npx sable init — once the package is installed

init reads your package manager from the lockfile and your framework from the project. It installs what is missing (React, Tailwind and its build plugin), puts the CSS imports below in order, adds React dedupe and the Tailwind plugin to a Vite config, loads the fonts, mounts IconProvider in a Vite starter's entry, installs the agent skill and its block in AGENTS.md / CLAUDE.md (sable setup --agent), offers the Claude Code Stop hook when you run it in a terminal, then runs sable doctor. Anything it cannot change safely — an unfamiliar config, a Next.js layout — it prints as the exact snippet and the file it belongs in. Vite and Next.js (App Router) get every step; other setups get the packages and the stylesheet. --dry-run shows every change first; --no-agent skips the skill. Already set up? sable doctor --fix applies the same fixes to whatever doctor flags.

The steps below are what init does, for doing it by hand or checking its work.

1. Install:

pnpm add @sableui/react

2. Dedupe React, or Base UI resolves a second copy → "invalid hook call". Vite:

// vite.config.ts
export default defineConfig({ resolve: { dedupe: ["react", "react-dom"] } })

3. CSS (order matters), in your root stylesheet:

@import "tailwindcss";
@import "@sableui/react/styles.css";
/* let Tailwind scan the package for the classes its components use */
@source "../node_modules/@sableui/react/dist/**/*.{js,mjs}";

That @source generates the classes of every Sable component, about 32 KB of CSS gzipped. Once the app is built, npx sable sources --write src/sable-sources.css writes @source lines for just the modules it imports (12 KB for an app using Card, Button and DataTable); @import "./sable-sources.css"; in place of the line above. Re-run it after importing something new: sable check fails while the file is stale, since an unlisted component renders unstyled.

4. Fonts — the default theme expects Figtree (sans) + DM Mono (mono). Each alternate preset declares its own families in its manifest (registry.json → themes.available[].fonts). Load whichever stacks you plan to use via <link> or @font-face; the theme manifests declare the stacks but ship no font files.

5. Providers + color mode / theme selection:

import {
  IconProvider,
  MotionProvider,
  SableThemeProvider,
  ThemeSelector,
  ThemeSwitcher,
  useSableTheme,
} from "@sableui/react"
import { reiconIconSet } from "@sableui/react/icons/reicon"

function ThemeControls() {
  const { preference, setPreference, themeId, themes, setThemeId, mode } = useSableTheme()

  return (
    <>
      <ThemeSelector value={themeId} onValueChange={setThemeId} themes={themes} mode={mode} />
      <ThemeSwitcher value={preference} onValueChange={setPreference} />
    </>
  )
}

<IconProvider set={reiconIconSet}>       {/* required — Reicon, or pass another icon set */}
  <MotionProvider>                    {/* optional — enables the motion on/off toggle */}
    <SableThemeProvider>              {/* optional, recommended when users can switch themes */}
      <App />
    </SableThemeProvider>
  </MotionProvider>
</IconProvider>

Icons are opt-in: mount <IconProvider set={reiconIconSet}> once at the app root, with reiconIconSet from @sableui/react/icons/reicon (its only import path). Without a provider every <Icon> renders nothing, and a development build warns once. An app that passes its own set ships none of Reicon's artwork. To add domain icons, use composeIconSets(appExtras, reiconIconSet); composeIconSets and the IconSet type are exported from the root. A set returns null for names it does not handle. List the names your extras add in .sable/icons.json ({ "names": [...] }) so sable grade counts them as icons the app supplies, not off-contract ones. fallbackIconSet remains a deprecated alias of Reicon, exported from @sableui/react/icons/reicon. SableThemeProvider is the preferred route for user-facing theme switching: it stores the user's color preference (light / dark / system), toggles the .dark class, stores the active design theme, and writes data-sable-theme for non-default themes. If your app already owns this state, use applySableColorMode() / applySableTheme() or the exported SABLE_THEME_ATTRIBUTE constant directly. You do not need a Tailwind @custom-variant dark for Sable itself — add one (@custom-variant dark (&:where(.dark, .dark *));) only if your own app code uses dark: utilities (Sable ships none).

6. Use it:

import { Button, Card, Carousel, Dialog } from "@sableui/react"

The CLI

Two binaries ship with the package, both zero-dependency and both reading the contract from the version you actually installed:

npx sable pattern --list                     # the eight canonical page shells
npx sable pattern DashboardPage --skeleton   # its composition tree — 127 lines of source, 45 of structure
npx sable block PricingCardBlock --code      # a section-sized block's source, imports included
npx sable component Button --props
npx sable search "date range"                # one ranked set across components, examples, patterns, layout, tokens, docs
npx sable component Calendar --example Range # just the example a search hit names
npx sable init                               # wire a new app: packages, CSS, fonts, IconProvider, agent skill, then doctor
npx sable doctor                             # is this project wired correctly? exits 1 if not
npx sable doctor --fix                       # apply the fixes doctor can make safely; print the rest
npx sable docs designing-a-surface           # brief, direction, composition, interaction, adaptation
npx sable docs developing-taste             # references, rendered directions, scoped judgment
npx sable atlas --search "editorial culture" --contrast --limit 3 --json  # a project's own atlas, if it has one
npx sable explore --template                # specification for three rendered alternatives
npx sable prefer --search "reading" --scope project:my-app --json
npx sable learn --search "editorial hierarchy" --json
npx sable grade src --json                   # code conformance; pattern similarity is descriptive
npx sable grade --template                   # evidence record for a rendered design review
npx sable-lint                               # run the design contract over ./src

registry.json is about 1 MB and llms-full.txt about 800 KB — complete, and larger than any working context. sable serves the same generated content a piece at a time: --detail brief|compact|full picks a size, --dense drops prose, and --json wraps everything in a { type, data } envelope with a stable discriminator. Errors carry a stable code plus concrete suggestions, so a misspelled name costs one call instead of a guess. npx sable manifest --json describes the whole surface, generated from the same table that drives --help.

Design quality needs a rendered review. Start from the surface brief, reuse a canonical composition when it fits, or build an original one from layout primitives. Inspect desktop/mobile, the primary flow, keyboard behavior, and reduced motion; sable docs reviewing-a-design explains the evidence format. sable grade src --review design/review.json --strict validates conformance and recorded review completeness. It does not independently judge the images.

sable learn reads packaged precedents and project-owned .sable/lessons/ without a plugin or network. Each lesson states when to apply it, when to avoid it, and where its evidence came from. Use sable learn --template, fill observed before/after evidence, and sable learn --record design/lesson.json to preserve a provisional local lesson. Package upgrades never overwrite project memory. See sable docs learning-from-builds for the full loop.

Documentation

  • AGENTS.md — how to build with Sable: wiring, the rules for code you write, customizing (read first).
  • CONTRIBUTING.md — changing the package: hard rules, adding a component, theme/icon/motion contracts.
  • DESIGN.md — the design-system spec (tokens, type, grid, motion).
  • registry.json / llms.txt — machine-readable catalog + the consume recipe. Component entries include props, variants, tokens, a11y notes, copy-pasteable examples, and AI-readable usage guidance with do/don'ts, anatomy, keywords, and related components.

Build & publish

In the workspace the package is consumed as source (exports point at ./src) for instant HMR — no build needed for local dev. To produce the publishable artifact:

pnpm --filter @sableui/react build   # regenerates registry.json from the metas → tsup → dist/ (ESM + .d.ts) → copies the token CSS

Requires Node 22+ (the registry generator imports the .meta.ts files via Node's built-in TypeScript type-stripping). registry.json is generated from each component's *.meta.ts; CI's pnpm registry:check fails the build if it drifts.

publishConfig.exports repoints consumers at ./dist on publish (workspace dev keeps ./src). Publishing is automated — push a v* tag and the repo's Release GitHub Action publishes to npm with provenance (see the repo-root README).

Requirements

  • React 19 (peer), React DOM 19 (peer), Tailwind CSS v4 in the consuming app.

Build with an agent

After installing Sable, run pnpm exec sable setup --agent in the target project. It installs discoverable entry files in .agents/skills/sable for Codex/Cursor and .claude/skills/sable for Claude Code; --target selects a host. In a monorepo where Sable belongs to one workspace package, run setup in that package with --root naming the repository root (for example pnpm --filter web exec sable setup --agent --root ../..); the entries go there and resolve Sable through the package. Setup also adds a short managed block to the project's AGENTS.md and CLAUDE.md, the instructions an agent reads on every task, so a UI request goes through the skill even when it doesn't mention Sable. Only the text between its <!-- sable:begin --> and <!-- sable:end --> markers is Sable's; --no-instructions skips it. Each entry resolves skills/sable/SKILL.md from the installed package, so package upgrades also update the workflow. Other agents can read that file directly. Use $sable build <idea>, inspire <references>, audit <target>, or polish <target> in Codex; use /sable with the same modes in Claude Code or Cursor. create is a build alias. These are agent modes, not shell commands.

To look Sable up before installing it, or if you prefer MCP, add the hosted server: claude mcp add --transport http sable https://www.sableui.com/api/mcp (Cursor, VS Code and Codex take the same URL). Its three tools, search, get and docs, give the CLI's answers from the published package, at the version the agent passes or the latest. Once Sable is installed, the CLI is the default.

Upgrade with pnpm exec sable upgrade: it updates the package, then runs the new version's init, which refreshes the skill entries and the instructions block and checks the wiring. From 0.17 or earlier, which has no upgrade, run pnpm update @sableui/react --latest and then pnpm exec sable init once. Setup only replaces managed files that have not been locally edited; --dry-run checks without writing. Keep project preferences in project instructions. Package installation alone does not change agent settings. See building-with-sable.md, creating-a-preset.md, and using-presets.md.