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

@kismet-ux/constellation

v1.11.1

Published

Kismet Constellation — a themeable React component library: design tokens, light/dark, and 60+ router-agnostic components.

Readme

Kismet Constellation

A themeable React component library. ~60 components, light/dark out of the box, and a design-token system where one file holds every color decision.

No router dependency, no bundled fonts, no registry, no brand baked in — it's meant to be copied into a project and made yours.

npm install
npm run dev     # → http://localhost:5173

The dev server opens on Foundations, a live showcase of the whole token system: color families, type scale, spacing, radius, elevation, and components in context. Every other component has its own preview page in the sidebar.

Append ?theme=light, ?theme=dark, or ?theme=system to pin the mode.


Two ways to use it

Copy the repo (what it's designed for) — you own the source, and rebranding means editing _palette.scss and _theme.scss as described below.

Install it as a dependency:

npm install @kismet-ux/constellation
import '@kismet-ux/constellation/styles';
import { Button } from '@kismet-ux/constellation/ui';

You only pay for what you render. Each component ships its own stylesheet, imported by the component itself, so your bundler drops the CSS for everything you don't use — the same way it drops the JS. Importing …/styles gives you the tokens and reset (4.6 kB gzipped); each component adds its own on top.

Installed, the SCSS is already compiled, so the two-file seam isn't available to you — retheme by overriding the custom properties after importing the stylesheet. Every token in the next section is fair game:

@import '@kismet-ux/constellation/styles';

:root {
  --primary-main: #7c3aed;
  --primary-emphasis: #6d28d9;
  --font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
}
:root:not([data-theme='light']) { /* your dark overrides */ }

Making it yours

1. Color

Everything routes through two files:

| File | Holds | |---|---| | src/styles/_palette.scss | The raw ramps — $sky-500, $slate-900, … | | src/styles/_theme.scss | The mapping to CSS custom properties, light and dark |

No component names a color. Change the ramps and the entire library follows.

Seven theme families ship by default — primary (sky), secondary (violet), info, success (emerald), warning (amber), destructive (rose), slate — and every one exposes the same ten roles:

main · dark · emphasis · light · contrast
focus · focus-visible · hover · outlined-border · selected

That uniformity is what lets any component accept a theme prop and behave predictably:

<Button theme={'success'}>Save</Button>
<Chip theme={'warning'}>Pending</Chip>
<StatCard theme={'info'} label={'Queries'} value={42} />

Two ramp shapes, chosen on purpose:

  • Alpha tints (25–400) for states that sit over an unknown surface — hover, selected, focus. They compose correctly on light and dark without knowing what's behind them.
  • Solid shades (500–950) for text and fills, where the value must be exact.

$info-* is the per-channel midpoint of $slate-* and $sky-*, shade for shade. Same hue as primary at lower chroma — which is what makes "info" read as the quiet informational tone rather than a competing accent. If you re-pick the primary, regenerate info the same way.

2. Type

--font-sans, --font-serif and --font-mono resolve to system stacks. Nothing to download, nothing to license, no flash of unstyled text. To brand it, override one variable:

:root { --font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif; }

src/styles/_fonts.scss has a font-face mixin and notes for self-hosting.

3. Brand

<Logo /> is a geometric mark plus a text wordmark — no baked-in SVG paths:

<Logo name={'Acme'} />                   {/* rename */}
<Logo name={'Acme'} mark={<YourMark />} />  {/* or replace the glyph */}
<Logo name={null} />                     {/* mark only */}

Colors come from --logo-mark and --logo-fill. Inside a collapsed sidebar the wordmark folds away and the mark holds its place.

4. Space, radius, elevation

  • --size-1--size-12, where --size-N is N ÷ 2 rem. No magic numbers.
  • --radius-xs|sm|md|lg|xl|2xl|full.
  • 24 elevation levels. In light mode height is carried by a two-layer key + ambient shadow; in dark mode, where shadow reads as nothing, by a progressively lighter surface. Both ramps are generated in _theme.scss — change the formula once, not 24 times.

Routing

The library never imports a router. Out of the box Link renders a plain <a> and navigation is a full page load — correct everywhere, just not SPA-fast.

Wrap the app once and every link, breadcrumb, sidebar item and menu action upgrades together:

import { RouterProvider } from '@kismet-ux/constellation/navigation';
import { Link, useNavigate } from 'react-router-dom';

<RouterProvider linkComponent={Link} navigate={useNavigate()}>
  <App />
</RouterProvider>

Works the same with Next, TanStack Router, or anything else that exposes a link component and an imperative navigate.

Components take data, never globals: AppShell takes defaultSidebarOpen, NavUser takes user plus onSettings / onLogout.


Layout of the repo

src/
  styles/      ← _palette.scss + _theme.scss: the theming seam
  ui/          Button, Dialog, Table, Chip, Alert, StatCard, …
  form/        Input, Select, Checkbox, DatePicker, Label
  layout/      AppShell, Sidebar, Container, Row, Column, Grid
  navigation/  Link, RouterProvider, Breadcrumbs, DropdownMenu, Sheet
  typography/  Typography, Heading, TruncatedText
  settings/    appearance switchers
  user/        UserInfo, UserMenuContent
  brand/       Logo
  hooks/       useAppearance, useBreakpoint, useAlerts, useTableSorting, …
dev/           the preview harness you see at localhost:5173

Each component is a folder: component-name.tsx + component-name.module.scss + index.ts.


Developing it against a real app

Publishing a version for every small change is how versioning goes off the rails. Instead, point a consuming app at a sibling checkout:

projects/
  kismet-constellation/   ← this repo
  your-app/

In the app's vite.config.js:

import constellationLocal from '@kismet-ux/constellation/vite';

export default defineConfig({
  plugins: [constellationLocal({ root: '../kismet-constellation' }), react()],
});

…and in its .env.local:

CONSTELLATION_LOCAL=true

The plugin builds resolve aliases from this package's own exports map, so there is no alias list to maintain. It aliases to dist, so keep a build running:

npx rollup -c --watch

__CONSTELLATION_LOCAL__ is defined as true while it is on, which is what DevIndicator reads to show its badge. With the variable unset the plugin is inert and the app uses the published package, so nothing depends on the checkout existing.

⚠️ The plugin appends to server.fs.allow, and must. Setting that option at all replaces Vite's default, so listing only the library root locks the consuming app out of its own source — every module 403s and the page renders blank with no useful error.

Commands

npm run dev        # dev harness
npm run build      # bundle + type declarations → dist/
npm run typecheck  # tsc --noEmit
npm run lint       # eslint --fix
npm run stylelint  # alphabetical SCSS property order
npm run format     # prettier

Notes for agents

AGENTS.md documents the architecture and conventions; .claude/skills/constellation-* carry per-category component references. Load the relevant skill before editing in a category.