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

@waukeshamakerspace/design-tokens

v2.0.0

Published

Waukesha Makerspace brand + semantic design tokens: CSS variables with automatic light/dark theming, Tailwind (v3 + v4) and MUI adapters

Downloads

747

Readme

@waukeshamakerspace/design-tokens

npm

Waukesha Makerspace brand + semantic design tokens, extracted from the token system pioneered in makers-cms. One package, consumed by every WMI UI, so the brand hexes live in exactly one place.

  • Brand layer (fixed): Burnt Orange #E8600A, Charcoal #2B2B2B, Golden Yellow #F5A623, Warm White #F7F3EE — from marketing/brand/brand-guidelines.md.
  • Semantic layer (themable): surface, foreground, border, primary, secondary, accent, link, ring, warning/success/danger, each with light and dark values. Components use these, never brand hexes. Since v2, accent follows the shadcn contract (subtle hover/selected background for menus and lists); for golden yellow use the brand layer (bg-golden-yellow / var(--brand-golden-yellow)) or warning.
  • Fonts: Oswald (headings) + Open Sans (body), wired via --font-heading / --font-body.

Cross-cutting UI rules (mobile-first, device-theme behavior, accessibility) live in the architecture repo: waukesha-makers-architecture/shared/ui-guidelines.md.

Install

Published on the public npm registry at npmjs.com/package/@waukeshamakerspace/design-tokens — install it like any other public package. No auth, no custom registry config, no git/file dependency. Consuming projects must depend on the npm package, never on a local checkout of this repo.

npm install @waukeshamakerspace/design-tokens

Enable Renovate or Dependabot in consuming apps so new token releases arrive as automatic bump PRs.

Dark mode model

css/tokens.css resolves the theme in this order:

  1. .dark / .light class on <html> wins (set pre-paint by the theme-init script, or by an app-level toggle).
  2. No class present → the OS prefers-color-scheme applies via media query.

So plain-CSS consumers follow the device theme with zero JS. Apps using class-based styling (Tailwind dark:, MUI color schemes) inline the theme-init script so the class follows the device too:

// Next.js: in app/layout.tsx <head>, before first paint
import { themeInitScript } from '@waukeshamakerspace/design-tokens/theme-init';

<script dangerouslySetInnerHTML={{ __html: themeInitScript }} />
// SPA: top of the entry module
import { initTheme } from '@waukeshamakerspace/design-tokens/theme-init';
initTheme();

?theme= testing override

?theme=light|dark in any URL wins over everything for that page load — the standard WMI testing knob, built into the init script and initTheme(). It sets the same override flag as setTheme, so OS-change syncing stays suppressed until reload.

Non-standard setups

buildThemeInitScript(options) bakes options into the inline script:

import { buildThemeInitScript } from '@waukeshamakerspace/design-tokens/theme-init';

// Digital signage: force dark (never follow a TV's prefers-color-scheme);
// ?theme= still wins for testing.
buildThemeInitScript({ defaultMode: 'dark' });

// A sub-tree owns its own theming (it inlines its own script): tell the
// root-layout script to leave those paths alone.
buildThemeInitScript({ skipPathPrefixes: ['/signage'] });

initTheme(window, { defaultMode }) accepts the same defaultMode for SPAs.

On-the-fly theme switching

Every app must expose a simple toggle so both modes can be exercised during development (see shared/ui-guidelines.md). Build it on the exported helpers so it coordinates with the OS-change listener instead of fighting it:

import { toggleTheme, setTheme, getTheme } from '@waukeshamakerspace/design-tokens/theme-init';

<button onClick={() => toggleTheme()}>Theme</button>
// or explicit: setTheme('dark') / setTheme('light') / setTheme('system')

An explicit choice persists across visits (localStorage key wm-theme) and is restored pre-paint by the init script, so there is no flash of the wrong theme. setTheme('system') clears the stored choice and resumes following the device, which remains the default for users who never chose. Choices made in one tab are mirrored live into other open tabs, in any app that called initTheme() or has a subscribeTheme() listener mounted (the inline script alone applies stored choices at load, not live).

Reacting to theme changes

Every applied change (a setTheme call, an OS-theme change while following the device, a choice from another tab) dispatches a wm-theme-change CustomEvent on window. subscribeTheme wraps all the listeners:

import { subscribeTheme, getThemeMode, getTheme } from '@waukeshamakerspace/design-tokens/theme-init';

const unsubscribe = subscribeTheme(({ mode, theme }) => {
  // mode:  'light' | 'dark' | 'system'  (the user's choice)
  // theme: 'light' | 'dark'             (what's actually applied)
});

React apps should prefer the useThemeMode() hook from @waukeshamakerspace/react-components, which is built on this.

Usage

Tailwind v4 (makers-cms style)

/* globals.css */
@import "tailwindcss";
@import "@waukeshamakerspace/design-tokens/css/tailwind.css";

Gives every token as a utility (bg-surface, text-foreground-muted, bg-primary hover:bg-primary-hover, font-heading) plus a class-based dark: variant.

shadcn components (Tailwind v4 only)

css/tokens.css ships shadcn's CSS variable contract, so vendored shadcn source (as in @waukeshamakerspace/react-components) themes correctly in both modes with no per-component CSS:

  • Bridge aliases in :root: --background, --card, --popover, --muted, --destructive, --input, and their -foreground partners, each pointing at the matching semantic token. --foreground, --primary, --secondary, --accent, --border, and --ring are native semantic tokens whose names and meanings already match shadcn's.
  • --radius: 0.625rem, with the v4 layer deriving the shadcn rounded-sm/md/lg/xl scale from it. Note this overrides Tailwind's default radius scale for those four sizes.
  • font-sans maps to the brand body font (Open Sans).

Deliberate omissions: chart-* and sidebar-* variables (added when an app needs them), and no bridge in the Tailwind v3 preset (react-components requires v4).

Caveat: the alias names are generic; an app that defines its own --background (or any other bridge name) on :root after importing tokens.css will retheme shadcn components. To re-skin a subtree, override the alias name (--card), not the token behind it (--surface-raised); alias substitution happens on :root, so subtree overrides of the underlying token don't flow through.

Tailwind v3

// tailwind.config.js
module.exports = {
  presets: [require('@waukeshamakerspace/design-tokens/tailwind-preset')],
  // ...
};
/* global stylesheet */
@import "@waukeshamakerspace/design-tokens/css/tokens.css";

Same utility names as v4. Caveat: opacity modifiers (bg-primary/50) don't work on var()-based colors in v3.

MUI v6+

import { createMakersTheme } from '@waukeshamakerspace/design-tokens/mui';

const theme = createMakersTheme(); // pass overrides to deep-merge
<ThemeProvider theme={theme}>...</ThemeProvider>

Light/dark schemes flip on the same .light/.dark class (via MUI cssVariables.colorSchemeSelector), so MUI stays in sync with the CSS tokens. themeOptions is also exported if you'd rather call createTheme yourself.

Plain CSS / anything else

@import "@waukeshamakerspace/design-tokens/css/tokens.css";

.card {
  background: var(--surface-raised);
  color: var(--foreground);
  border: 1px solid var(--border);
}

Fonts

Next.js apps: load Oswald + Open Sans with next/font and map them to --font-heading / --font-body (see makers-cms layout.tsx). Everything else: @import "@waukeshamakerspace/design-tokens/css/fonts.css"; (loads Google Fonts and wires the variables).

Brand assets (logos + favicons)

The package ships the logo masters and a favicon set generated from them:

| Path | What it is | | --- | --- | | assets/logo.png | Full logo, dark artwork, transparent, 1500×1500 | | assets/logo-white.png | Full logo, white artwork, transparent, 1500×1500 | | assets/logo-white-bg.png | Full logo on opaque white, 1500×1500 — favicon-set master | | assets/favicon.ico | 16/32/48 multi-size, white background | | assets/apple-touch-icon.png | 180×180, white background | | assets/icon-192.png / assets/icon-512.png | PWA / web-manifest icons, white background |

Bundler apps (Vite, webpack, Next <Image>/metadata): import the file — the bundler hashes the URL, so rebrands bust caches automatically.

import logo from '@waukeshamakerspace/design-tokens/assets/logo.png';
// Next.js app router: app/layout.tsx
import favicon from '@waukeshamakerspace/design-tokens/assets/favicon.ico';
import appleIcon from '@waukeshamakerspace/design-tokens/assets/apple-touch-icon.png';

export const metadata = {
  icons: { icon: favicon.src, apple: appleIcon.src },
};

Anything that needs the files in public/: copy at build time, e.g.

// package.json
"prebuild": "cp node_modules/@waukeshamakerspace/design-tokens/assets/favicon.ico public/"

Token values in JS

import { brand, light, dark, fonts, radius, shadcnAliases } from '@waukeshamakerspace/design-tokens';

Editing tokens

index.js is the single source of truth for values; the masters for imagery are assets/logo.png / assets/logo-white.png (app-facing) and assets/logo-white-bg.png (favicon set). Edit those, then:

npm run build   # regenerates css/tokens.css + the assets/ favicon set

Never edit css/tokens.css or the generated icons (favicon.ico, apple-touch-icon.png, icon-*.png) by hand. Brand-layer changes must go through marketing/brand/brand-guidelines.md first.

Releasing

Automated by release-please. Write Conventional Commits (fix: → patch, feat: → minor, feat!: → major); pushes to main accumulate into a release PR, and merging it publishes to npm. Don't bump version by hand.