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

@hex-core/tokens

v1.3.4

Published

Design token engine for Hex Core — HSL tokens + typography scale shared between components and themes.

Readme

@hex-core/tokens

npm downloads License: MIT

Design token engine for Hex Core — HSL color tokens + typography scale + shadow/radius tokens shared between components and themes.

Install

pnpm add @hex-core/tokens

Or, more commonly, copy the CSS block from the Theming guide directly into your app's globals.css.

Contents

  • Light + dark HSL palette (zinc neutral base, WCAG-safe pairs)
  • Typography scale (--text-2xs--text-5xl)
  • Radii (--radius-sm/md/lg)
  • Shadows (--shadow-glow)
  • Container widths

CSS variable namespaces

Tokens live in two namespaces depending on which layer is reading them. Knowing the contract avoids surprises when you author globals.css, override at runtime, or wire Tailwind v4.

--<key> — raw values, key-only namespace (source of truth)

themeToCss(theme) emits CSS custom properties using the raw value verbatim, with no hsl() wrapper and no --color- prefix. The exact shape of the value depends on the token type — colors are stored as H S L triplets in the bundled themes, radii as lengths, durations as times, etc. themeToCss doesn't transform the value; it just writes it under --<key>.

@layer base {
  :root {
    --background: 0 0% 100%;       /* color, stored as triplet */
    --foreground: 240 10% 3.9%;
    --primary: 240 5.9% 10%;
    --radius-md: 0.5rem;            /* length */
    --duration-fast: 150ms;         /* time */
  }

  .dark {
    --background: 240 10% 3.9%;
    --foreground: 0 0% 98%;
    /* … */
  }
}

Why store colors as triplets: alpha composition. hsl(var(--background) / 0.5) requires the var to hold 0 0% 100%, not hsl(0 0% 100%). Utilities like bg-background/50 and ring/border opacity overrides depend on this — wrapping at the source forfeits them.

themeToFlatJson() shares this namespace (returns Record<"--<key>", string> for AI/LLM consumption).

--color-<key> — Tailwind v4 @theme (consumption)

Tailwind v4's @theme directive demands a --color-<key> namespace to auto-generate utilities like bg-background, text-foreground, border-input. The docs site authors this layer by hand in apps/docs/src/app/globals.css:

@theme {
  --color-background: hsl(0 0% 100%);
  --color-foreground: hsl(240 10% 3.9%);
  --color-primary: hsl(240 5.9% 10%);
}

.dark {
  --color-background: hsl(240 10% 3.9%);
  /* … */
}

This shape has the hsl() wrapper and the --color- prefix — different from the raw layer.

Bridging both layers (recommended for v4 consumers)

If you want one source of truth plus Tailwind v4 utilities, declare the raw values at :root/.dark and delegate from @theme:

@theme {
  --color-background: hsl(var(--background));
  --color-foreground: hsl(var(--foreground));
  /* … */
}

:root {
  --background: 0 0% 100%;
  --foreground: 240 10% 3.9%;
}

.dark {
  --background: 240 10% 3.9%;
  --foreground: 0 0% 98%;
}

Now your runtime overrides (.theme-vivid { --background: 270 100% 95%; }) only need to touch the raw layer — Tailwind utilities follow automatically because @theme resolves var(--<key>) at paint time.

Use plain @theme, not @theme inline. The inline form substitutes the value at build time and would freeze the var(--<key>) lookup to whatever the variable resolved to during build, breaking the bridge. The non-color tokens in the docs site use @theme inline deliberately because they're static (radii, font sizes); colors stay in plain @theme so the cascade works.

The docs site itself doesn't bridge — it inlines hsl(...) directly in @theme and re-declares colors in .dark. That's intentional: the docs app never round-trips through themeToCss, so a separate raw layer would just be duplication. Bridge when you ship to v4 consumers AND you need them to override raw values in custom themes (.theme-foo { --background: ... }).

Runtime overrides — themeToScopedRuntimeCss

When an app needs to flip themes at runtime without round-tripping through globals.css (e.g. a theme studio's preview canvas, a per-org branding scope, a user-customized palette stored in URL state), use themeToScopedRuntimeCss(theme, { scope?, mode? }). It emits a single CSS rule that drops both namespaces in one call:

import { defaultTheme, themeToScopedRuntimeCss } from "@hex-core/tokens";

const css = themeToScopedRuntimeCss(defaultTheme, {
  scope: ".studio-canvas-active",
  mode: "light",
});
// →
// .studio-canvas-active {
//   --background: 0 0% 100%;
//   --color-background: hsl(0 0% 100%);
//   --primary: 240 5.9% 10%;
//   --color-primary: hsl(240 5.9% 10%);
//   --radius-md: 0.5rem;
//   /* … */
// }

Inject via a <style> tag and the override applies to every descendant of the scoped element — Tailwind utilities resolve through @theme, alpha-composition utilities (bg-background/50, border-border/30) resolve through the raw layer.

scope defaults to :root. mode defaults to "light"; pass "dark" to render the dark palette (typically combined with a .dark selector applied by your theme provider).

Non-color tokens (radii, durations, spacing, font sizes) only emit the raw --<key> form — they don't go through @theme's color machinery.

Tailwind v3 helper

themeToTailwindConfig(theme) returns the same Tailwind layer for the v3 config-file style:

import { defaultTheme, themeToTailwindConfig } from "@hex-core/tokens";

export default {
  theme: { extend: themeToTailwindConfig(defaultTheme) },
};

Output uses hsl(var(--<key>)) references (no --color- prefix needed in v3).

generateGlobalsCss is also Tailwind v3 — it wraps themeToCss output with @tailwind base/components/utilities directives. Don't use it inside a Tailwind v4 project.

Overriding

Every token is a CSS custom property. Override on :root or inside .dark for per-theme overrides. See the Theming guide for examples (accent hue swap, custom palette, typography scale).

Docs

hex-core.dev/docs/theming

License

MIT