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

@serenis/design-tokens

v0.22.0

Published

Design tokens for the Serenis design system. Generates typed JS constants, CSS custom properties, cssvar accessor helpers, and CSS utility classes — all from a single set of [DTCG](https://tr.designtokens.org/format/) JSON files.

Downloads

229

Readme

@serenis/design-tokens

Design tokens for the Serenis design system. Generates typed JS constants, CSS custom properties, cssvar accessor helpers, and CSS utility classes — all from a single set of DTCG JSON files.

See ADR-0011 for architectural decisions.

Install

npm install @serenis/design-tokens

Import the CSS bundle in your app entry point:

import '@serenis/design-tokens/css'

Sub-paths for advanced use cases: @serenis/design-tokens/css/base, @serenis/design-tokens/css/serenis-light, @serenis/design-tokens/css/serenis-dark, @serenis/design-tokens/utilities.

Quick start

# Build all outputs (codegen + CSS + JS bundle)
yarn workspace @serenis/design-tokens build

# Run tests (includes golden snapshot tests)
yarn workspace @serenis/design-tokens test

# Update golden snapshots after intentional changes
yarn workspace @serenis/design-tokens test -- -u

Directory structure

libraries/design-tokens/
├── tokens/                    # DTCG JSON source files
│   ├── root.json              # Base tokens (all types)
│   ├── serenis-light.json     # Light theme overrides
│   ├── serenis-dark.json      # Dark theme overrides
│   ├── aliases.json           # Semantic alias tokens
│   ├── tablet.json            # Responsive overrides (≥601px)
│   └── desktop.json           # Responsive overrides (≥1025px)
├── src/
│   ├── stories/               # Storybook stories and documentation (colocated)
│   │   ├── Breakpoints/
│   │   ├── Color/             # Color stories + Overview.mdx doc page
│   │   ├── Dimensions/
│   │   ├── Effects/
│   │   ├── Typography/
│   │   ├── UtilityClasses/
│   │   ├── components/        # Shared story helper components
│   │   └── docs/              # Domain-specific doc helpers for MDX pages
│   │       ├── components/    # Category-specific doc components (ColorPairing, etc.)
│   │       └── utils/         # Token description extractors (reads $description from JSON)
│   └── utils/                 # Hand-written runtime helpers (compiled → dist/utils/)
├── scripts/
│   ├── pipeline/              # Build pipeline entry + Style Dictionary config
│   ├── codegen/               # TypeScript module generators
│   ├── cssUtilities/          # CSS utility class generator
│   └── shared/                # JSON reader, token key sorting
├── dist/                      # Generated JS/DTS modules + CSS (gitignored)
│   ├── types/                 # Token name arrays + union types
│   ├── constants/             # UPPER_SNAKE_CASE constants (var refs + raw values)
│   ├── cssvar/                # Typed accessor functions
│   ├── utils/                 # Compiled from src/utils/
│   └── *.css                  # CSS custom properties + utility classes
└── package.json

Documentation pages

MDX files under src/stories/ are picked up by Storybook as doc pages (configured in apps/design-system/.storybook/main.ts). These pages use design-token-based typography via docs-reset.css, which overrides Storybook's built-in styles.

Reusable building blocks for doc pages (SectionIntro, DosDonts, Table/Row, CodeExample) come from the storybook-docs library. Category-specific visual components (e.g. ColorPairing) live in src/stories/docs/components/. Token $description metadata is read by src/stories/docs/utils/tokenDescriptions.ts, so doc pages stay in sync with the JSON source automatically.

Story sort order puts "Overview" pages first, then "Playground", then everything else.

Writing an Overview page

Every token category should have an Overview.mdx file that follows a consistent structure. Use Color/Overview.mdx as the reference implementation.

Expected sections:

  1. Title + intro — Category name as # heading, one-line summary, then <SectionIntro> pulling $description from the token JSON source.
  2. Theme and responsive behavior — How these tokens behave across themes and viewports. Every Overview page includes this section for consistency.
  3. Conceptual model — How the tokens in this category are organized (layers, scales, naming logic). Use <Table> for structured breakdowns.
  4. Token-by-token guide with code examples — Walk through the main tokens/groups with usage guidance, rendered values, <CodeExample> blocks, and <DosDonts>. Code examples and guidelines are interleaved within each token subsection rather than gathered at the end.
  5. Accessibility / pairing notes (when relevant) — Contrast, motion, sizing, or other a11y considerations for this category. Not every category needs a dedicated section.

Imports:

import { Meta } from '@storybook/addon-docs/blocks'
import { CodeExample, DosDonts, Row, SectionIntro, Table } from 'storybook-docs'
import { rootDescriptions } from '../docs'
// For themed tokens (Color, Effects):
import { rootDescriptions, lightDescriptions, darkDescriptions } from '../docs'

Generic building blocks (SectionIntro, DosDonts, Table/Row, CodeExample) come from the storybook-docs library. Category-specific components (e.g. ColorPairing) live in src/stories/docs/components/. Token descriptions are pre-computed maps in src/stories/docs/utils/tokenDescriptions.ts — use rootDescriptions.spacing, lightDescriptions.color, etc. to get $description strings. This keeps docs in sync with the JSON source automatically.

How to consume

1. JS constants (styled-components)

import { COLOR_PRIMARY, SPACING_MD, BORDER_RADIUS_LG } from '@serenis/design-tokens'

const Card = styled.div`
  background: ${COLOR_PRIMARY};
  padding: ${SPACING_MD};
  border-radius: ${BORDER_RADIUS_LG};
`

Each constant resolves to var(--srns-spacing-md). A _VALUE companion holds the raw CSS value:

SPACING_MD // "var(--srns-spacing-md)"
SPACING_MD_VALUE // "16px"

2. CSS custom properties

@import '@serenis/design-tokens/css'; /* base + both themes + utility classes */
/* or granular: */
@import '@serenis/design-tokens/css/base'; /* root + responsive overrides */
@import '@serenis/design-tokens/css/serenis-light'; /* base + light theme (standalone) */
@import '@serenis/design-tokens/css/serenis-dark'; /* base + dark theme (standalone) */

All variables are prefixed --srns- and scoped to :root (base) or .srns-serenis-light / .srns-serenis-dark (themes).

3. Cssvar accessor helpers

import { cssvarSpacing } from '@serenis/design-tokens'

cssvarSpacing('md')
// → { name: 'srns-spacing-md', value: 'var(--srns-spacing-md)' }

Typed: cssvarSpacing only accepts valid SpacingName values.

4. CSS utility classes

/* app.css */
@import '@serenis/design-tokens/utilities';

This gives you utility classes mapped to design tokens: bg-primary-50, p-md, px-lg, mb-sm, rounded-lg, elevation-sm, font-600, etc. Typography composites are available as typography-paragraph, typography-public-h1, etc. Directional spacing uses short Tailwind-style names (px/py/pl/pr/pt/pb for padding, mx/my/ml/mr/mt/mb for margin), mapped to CSS logical properties under the hood. No external CSS framework required; the output is plain CSS compatible with Safari 16+.

Responsive variants

Some utility classes are available with a mobile-first breakpoint prefix, following the pattern {bp}\:{utility}. Three breakpoints are supported:

| Prefix | Media query | | ------ | ------------------- | | md | min-width: 601px | | lg | min-width: 1025px | | xl | min-width: 1441px |

For example, md\:flex applies display: flex when the viewport is at least 601px wide.

Utilities with responsive variants:

  • Spacing padding (p-*, px-*, py-*, pl-*, pr-*, pt-*, pb-*)
  • Spacing margin (m-*, mx-*, my-*, ml-*, mr-*, mt-*, mb-*)
  • Spacing gap (gap-*, gap-x-*, gap-y-*)
  • Display (flex, grid, block, inline-flex, inline-block, hidden)
  • Flex direction (flex-row, flex-col)
  • Alignment (items-center, items-start, items-end, items-stretch)
  • Justify (justify-center, justify-between, justify-start, justify-end)
  • Flex wrap (flex-wrap, flex-nowrap)
  • Flex grow/shrink (grow, grow-0, shrink, shrink-0)
  • Flex basis (basis-1/12basis-11/12, basis-full, basis-auto, basis-{container})

Utilities without responsive variants: spacing sizing (w-*, h-*, size-* from spacing 0 only), container width (w-{container}, min-w-{container}, max-w-{container}), border radius (rounded-*), colors (bg-*, text-{color}, border-{color}), border width (border-*), elevation (elevation-*), z-index (z-*), font weight, font family, opacity (opacity-*), typography composites (typography-*), position, overflow, text-align, border-style, and transition.

cx helper

The build also generates a cx() helper for composing utility classes. It is typed via UtilityClassName, so you get autocomplete and compile-time checks. It also accepts object arguments for conditional classes — keys whose value is truthy are included in the output:

import { cx } from '@serenis/design-tokens'
;<div className={cx('p-md', 'bg-primary-50', 'rounded-lg')} />
;<div className={cx('pt-md', { [cx('pt-0', 'bg-primary-50')]: isLarge })} />

Linting: Two ESLint rules enforce cx() usage across the monorepo. enforce-cx-classname requires cx() for all className composition (no raw strings or template literals). cx-classnames-order enforces a deterministic CSS-property-based ordering of class arguments and removes duplicates — this rule is auto-fixable.

How to add a token

  1. Add to JSON: Edit the appropriate file in tokens/ (usually root.json). Follow the DTCG format:

    {
      "my-branch": {
        "$type": "dimension",
        "$description": "Description of this token group",
        "my-token": { "$value": { "value": 8, "unit": "px" } }
      }
    }
  2. Build: Run yarn workspace @serenis/design-tokens build. The pipeline auto-discovers branches by $type.

  3. Update snapshots: Run yarn workspace @serenis/design-tokens test -- -u to update golden snapshots.

  4. The new token is immediately available as:

    • JS constant: MY_BRANCH_MY_TOKEN / MY_BRANCH_MY_TOKEN_VALUE
    • CSS variable: --srns-my-branch-my-token
    • CSS utility class (e.g. my-branch-my-token)

How to add a theme

  1. Create a new JSON file in tokens/ with color/elevation overrides.

  2. Register it in scripts/pipeline/themeTokenRegistry.ts:

    { id: 'my-theme', tokenJsonFileName: 'my-theme.json', colorScheme: 'light' }
  3. Rebuild. The pipeline produces dist/my-theme.css and theme-specific JS constants automatically.

Token types

| DTCG $type | Token branches | Codegen | | ------------ | --------------------------------------------------------------------------------------------------- | ------------------------ | | dimension | spacing, container, border-radius, border-width, font-size, line-height, letter-spacing, breakpoint | Registry (simple) | | duration | time | Registry (simple) | | fontFamily | font-family | Registry (simple) | | fontWeight | font-weight | Registry (simple) | | number | opacity, z-index | Registry (simple) | | string | media-query | Registry (simple) | | shadow | elevation | Dedicated (theme layers) | | color | color | Dedicated (theme layers) | | typography | typography, typography.public | Dedicated (composite) |

"Registry (simple)" types share a unified codegen path via SIMPLE_TOKEN_RESOLVERS. Adding a new simple type means adding one entry to the registry in scripts/codegen/tokenTypeResolvers.ts.

Build pipeline

tokens/*.json
    │
    ├──▶ Custom codegen ──▶ dist/{types,constants,cssvar,utils}/*.{js,d.ts}
    │       │
    │       └──▶ esbuild CJS bundle ──▶ dist/index.cjs
    │
    ├──▶ Style Dictionary ──▶ dist/root.css, dist/{theme}.css, dist/tablet.css, dist/desktop.css
    │       │
    │       └──▶ Minify + assemble ──▶ dist/base.css, dist/serenis-light.css, dist/serenis-dark.css
    │
    ├──▶ Style Dictionary (utility classes format) ──▶ dist/utilities.css
    │       │
    │       └──▶ Extract class names ──▶ dist/types/utility-class.{js,d.ts} (UtilityClassName)
    │                                  + dist/utils/cx.{js,d.ts} (cx helper)
    │
    └──▶ Concat base + themes + utilities + minify ──▶ dist/index.css

Scripts

| Command | Description | | ---------------- | ------------------------------------------------------ | | build | Full build: codegen + Style Dictionary CSS + JS bundle | | test | Run all tests (includes golden snapshot tests) | | test:watch | Watch mode | | typecheck | TypeScript validation | | lint | ESLint | | lint:fix | ESLint with auto-fix | | prettify | Prettier formatting | | prettify:check | Check Prettier formatting without writing | | clean | Remove .turbo, build, dist, node_modules |

License

PolyForm Noncommercial 1.0.0 — see LICENSE for the full text.