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

@servicetitan/hammer-token

v3.0.2

Published

Design token system for the Hammer design system, built with [Style Dictionary v5](https://styledictionary.com/) and the [Design Tokens Community Group (DTCG) format](https://www.designtokens.org/tr/2025.10/format/).

Downloads

55,091

Readme

@servicetitan/hammer-token

Design token system for the Hammer design system, built with Style Dictionary v5 and the Design Tokens Community Group (DTCG) format.

Overview

This package transforms design tokens from JSON source files into multiple output formats for use across web applications. It generates JavaScript modules, SCSS variables, CSS utility classes, and TypeScript definitions to support both runtime and build-time token consumption.

Token Structure

Tokens follow the Design Tokens Community Group (DTCG) format.

Primitive Color Token

Primitive tokens have a static value and declare their Figma variable scope via $extensions["com.figma.scopes"]. An empty array means no scope restriction (the variable appears in all pickers).

{
  "$type": "color",
  "$value": "#ffffff",
  "$extensions": {
    "com.figma.scopes": []
  }
}

Semantic Color Token (with dark mode)

Semantic tokens reference primitives and include light/dark appearance variants under $extensions.appearance. Both light and dark repeat the $type and use $value.

{
  "$type": "color",
  "$value": "{status.color.info}",
  "$extensions": {
    "appearance": {
      "light": {
        "$type": "color",
        "$value": "{status.color.info}"
      },
      "dark": {
        "$type": "color",
        "$value": "{status.color.info}"
      }
    },
    "com.figma.scopes": ["STROKE_COLOR"]
  }
}

Composite Color Token (color + alpha)

Used for colors that need an alpha channel. The color field is a reference to a primitive token; the build system emits color-mix() in CSS output to preserve the live primitive CSS variable.

{
  "$type": "color",
  "$value": {
    "color": "{color.neutral.900}",
    "alpha": 0.08
  },
  "$extensions": {
    "appearance": {
      "light": {
        "$type": "color",
        "$value": { "color": "{color.neutral.900}", "alpha": 0.08 }
      },
      "dark": {
        "$type": "color",
        "$value": { "color": "{color.neutral.0}", "alpha": 0.08 }
      }
    },
    "com.figma.scopes": ["EFFECT_COLOR"]
  }
}

Dimension Token

Dimension tokens (sizes, radii, breakpoints) use a nested object for $value with value and unit fields.

{
  "$type": "dimension",
  "$value": {
    "value": 0.375,
    "unit": "rem"
  },
  "$extensions": {
    "com.figma.scopes": ["CORNER_RADIUS"]
  }
}

The $root Pattern

The $root pattern allows a token group to have a default value while still containing sub-tokens (e.g. interactive states). A node with $value cannot normally also have children; $root bridges this by placing the default value one level deeper.

"primary": {
  "$root": {
    "$type": "color",
    "$value": "{color.blue.500}"
  },
  "hover": {
    "$type": "color",
    "$value": "{color.blue.600}"
  },
  "active": {
    "$type": "color",
    "$value": "{color.blue.700}"
  }
}

You can reference the group directly as {background.color.primary} — the build system resolves it to the .$root token automatically. The $root segment is stripped from all generated names (e.g. --a2-background-color-primary, not --a2-background-color-primary-root).

Token Naming Conventions

  1. Path to name: JSON object paths become hyphen-separated names (CSS/SCSS) or PascalCase (JS exports).
  2. $root segments: Stripped from the path in all outputs.
  3. State suffixes: State names (hover, active) are included as-is in the hyphenated name and capitalized in PascalCase exports.

Build Output (/build/web)

All generated CSS variable names use the a2- prefix by default (e.g. --a2-background-color-primary).

The build process executes three sequential Style Dictionary builds — Primitive → Theme (semantic) → Component — and writes output to /build/web:

build/web/
├── index.js              # Main entry point
├── index.d.ts            # TypeScript definitions
├── types.d.ts            # Core types (TokenObj, Token)
└── core/
    ├── primitive.js              # Primitive tokens (JS)
    ├── primitive.scss            # Primitive tokens (SCSS)
    ├── primitive-variables.scss  # Primitive tokens map (SCSS)
    ├── primitive.d.ts            # Primitive tokens (TypeScript)
    ├── semantic.js               # Semantic tokens (JS)
    ├── semantic.scss             # Semantic tokens (SCSS)
    ├── semantic-variables.scss   # Semantic tokens map (SCSS)
    ├── semantic.d.ts             # Semantic tokens (TypeScript)
    ├── component.js              # Component tokens (JS)
    ├── component.scss            # Component tokens (SCSS)
    ├── component-variables.scss  # Component tokens map (SCSS)
    ├── component.d.ts            # Component tokens (TypeScript)
    ├── index.js                  # Core index
    ├── index.d.ts                # Core TypeScript definitions
    └── css-utils/                # CSS utility classes

File Types

*.js Files

ES6 named exports with static resolved values. Tokens with dark variants include an extensions.appearance.dark.value property.

import { BackgroundColorPrimary } from "@servicetitan/hammer-token/build/web/core/semantic";
// { value: "#0265dc", extensions: { appearance: { dark: { value: "#78bbfa" } } } }

Caution: Values are resolved at build time and do not respond to CSS variable changes at runtime. Use *.scss files when dynamic theming is needed.

*.scss Files

SCSS variables with var(--a2-name, fallback) syntax, supporting recursive reference chains and light-dark() for dark mode.

*-variables.scss Files

SCSS maps ($light, $dark, $nonColor) used by ThemeProvider.module.scss.

.d.ts Files

Auto-generated TypeScript definitions using the unified TokenObj type.

import { TokenObj } from "../types";
export declare const ButtonPrimaryBackgroundColor: TokenObj;

Utility Files (src/utils/)

token-helpers.js

Core helpers for token value extraction, reference resolution, and CSS fallback building. Key points:

  • Smart $root resolution: resolveReference automatically retries with .$root appended when a reference points to a group rather than a leaf token.
  • Memoized token map: buildTokenMap caches an O(1) name→token Map per dictionary instance via WeakMap.
  • Composite colors: { color, alpha } tokens emit color-mix(in srgb, var(--a2-name, #hex) N%, transparent) in CSS contexts, preserving the live primitive CSS variable reference. Static contexts (JS exports, SCSS maps) fall back to hex8.
  • buildFallbackWithRefs: Main entry point used by all formats. Builds recursive var(--name, ...) chains and inserts light-dark() at the level where light and dark values first diverge.

sd-transforms.js

Registers DTCG transforms and the dtcg transform group:

  • dtcg/set-token-names (preprocessor): Pre-sets token.name to the full hyphenated path before transforms run. Prevents false name-collision warnings for tokens with unresolvable references that skip the transform pipeline.
  • dtcg/name, dtcg/value, dtcg/cubic-bezier, dtcg/color-opacity: Path normalization, dimension formatting, cubicBezier→CSS, and composite color pass-through.

css-utils-format-utils.js

Pure functions that generate CSS utility class strings — generateBorderClasses, generateColorClasses, generateFontClasses, generateSpacingClasses. Each accepts a pre-resolved value (which may already contain a light-dark() expression built by buildFallbackWithRefs) and an optional prefix.

sd-formats.js

Registers all custom Style Dictionary output formats:

  • custom/scss-variables — SCSS variables with var() + light-dark() fallbacks.
  • custom/scss-variables-map — SCSS maps ($light, $dark, $nonColor / $token) for ThemeProvider.module.scss.
  • custom/es6-variable — ES6 named exports with static resolved values.
  • custom/CSSVariables:root {} block with CSS custom properties.
  • custom/CSSUtils/{prefix}All|Borders|Colors|Fonts|Spacing — CSS utility class files (registered for both "" and "a2-" prefixes).

The All format uses a single-pass loop over allTokens (one buildFallbackWithRefs call per token for the light value, a second only when a dark variant exists) feeding three output buckets. The dedicated Borders, Colors, Fonts, and Spacing formats use separate filter+map pipelines.

Figma Sync (src/utils/figma/)

Script to sync design tokens to Figma variables using the Figma REST API.

Features

  • Syncs all tokens (primitives, semantic, component) to a single Figma variable collection
  • Creates Light and Dark modes for appearance variants
  • Resolves primitive token references to actual values
  • Creates variable aliases for semantic/component tokens that reference other tokens
  • Handles $root pattern by creating separate variables for root and state variants
  • Uses path-based naming (e.g., color/blue/500, background/color/primary)
  • Applies Figma variable scopes so variables only appear in the relevant UI pickers
  • Only updates variables when values change; still sends scope-only updates when scopes need to be applied
  • Handles rate limiting with automatic retries

Directory

  • auth.js - Authentication and configuration
  • constants.js - Figma file and collection constants
  • errors.js - Custom error classes
  • get-token.js - OAuth2 token helper script
  • token-parsing.js - Token file loading, parsing, and flattening
  • token-resolution.js - Reference resolution and dependency sorting
  • token-conversion.js - Converting tokens to Figma format
  • figma-api.js - Figma API requests, collections, and modes
  • sync-primitives.js - Primitive token sync logic
  • sync-semantic.js - Semantic token sync logic
  • sync-components.js - Component token sync logic
  • sync-orchestration.js - Theme sync orchestration
  • sync-main.js - Main entry point and CLI
  • utils.js - Shared utility functions

Variable Scopes

Figma variables can be scoped so they only show in certain property pickers (e.g. a color variable only in stroke color, or a dimension only in corner radius).

Scopes are defined directly on each token in $extensions["com.figma.scopes"] — an array of Figma scope names (e.g. SHAPE_FILL, STROKE_COLOR, CORNER_RADIUS, FONT_SIZE). The sync reads this field when creating or updating variables; scopes are deduplicated before sending.

To change which pickers a token appears in, edit $extensions["com.figma.scopes"] in the token file.

Commands

  • pnpm figma:sync - Sync all tokens to Figma (default file)
  • pnpm figma:sync:file <fileKey> - Sync tokens to a specific Figma file
  • pnpm figma:test - Test Figma API access (default file)
  • pnpm figma:test:file <fileKey> - Test access to a specific Figma file
  • pnpm figma:validate - Validate token files without syncing
  • pnpm figma:get-token - Interactive OAuth2 token helper script

CLI Options: --file-key/-f, --dry-run, --verbose/-v, --full, --help/-h

Authentication

Supports Personal Access Tokens (PAT) and OAuth2 refresh tokens. Configure via environment variables or .figma-config.json (repo root, gitignored).

Environment variables:

| Variable | Description | | --------------------- | -------------------------- | | FIGMA_ACCESS_TOKEN | PAT | | FIGMA_CLIENT_ID | OAuth2 client ID | | FIGMA_CLIENT_SECRET | OAuth2 client secret | | FIGMA_REFRESH_TOKEN | OAuth2 refresh token | | FIGMA_FILE_KEY | Optional file key override |

.figma-config.json:

{
  "accessToken": "figd_...",
  "clientId": "your-oauth-client-id",
  "clientSecret": "your-oauth-client-secret",
  "refreshToken": "your-oauth-refresh-token"
}

Environment variables take priority over the config file. OAuth2 access tokens are cached in memory and refreshed automatically on expiry (~1 hour).

GitHub Actions:

- name: Sync tokens to Figma
  env:
    FIGMA_CLIENT_ID: ${{ secrets.FIGMA_CLIENT_ID }}
    FIGMA_CLIENT_SECRET: ${{ secrets.FIGMA_CLIENT_SECRET }}
    FIGMA_REFRESH_TOKEN: ${{ secrets.FIGMA_REFRESH_TOKEN }}
  run: pnpm figma:sync

Dry-run mode (--dry-run): validates and reads existing variables without writing. Reports counts of what would be created/updated/skipped.

Troubleshooting:

  • Auth errors: Verify credentials. For OAuth2, re-authenticate if refresh token has expired.
  • "Authentication Failed - Please Re-Login": OAuth2 refresh token expired or revoked.
  • 403 Forbidden: Token may lack organization-level access.
  • File not found: Check the file key and access permissions.
  • Rate limiting: Retried automatically with exponential backoff.
  • Refresh token rotation: Update credentials with the new token logged to stdout.
  • Run pnpm figma:test to diagnose issues before syncing; pnpm figma:validate to check token structure without API calls.

Development

Adding New Tokens

  1. Add token JSON files to src/global/primitive/ (primitives) or src/theme/core/ (semantic/component)
  2. Run pnpm build to regenerate output files
  3. Import tokens in your code using the generated files

Modifying Build Output

  • Transforms: Edit src/utils/sd-transforms.js
  • Formats: Edit src/utils/sd-formats.js
  • Build Configs: Edit src/utils/sd-build-configs.js
  • CSS Utils: Edit src/utils/css-utils-format-utils.js