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

@troychaplin/component2block

v0.3.1

Published

Generate WordPress theme.json and CSS token files from a single config for component libraries

Downloads

1,761

Readme

component2block

A design token generator for Storybook component libraries that target WordPress block themes. Define your tokens once in a single JSON config, and component2block generates everything both platforms need — CSS variables, @font-face declarations, base typography, WordPress theme.json, and PHP integration hooks.

The Problem

Building a component library that works in both Storybook/React and WordPress means maintaining design tokens in multiple formats. Colors, spacing, fonts, and typography settings need to exist as CSS custom properties for your components, as theme.json presets for the WordPress Site Editor, and as PHP hooks to wire it all together. Keeping these in sync manually is tedious and error-prone.

How It Works

You write one config file. The generator produces everything.

c2b.config.json                                single source of truth
    │
    │   npx c2b generate
    │
    ├──► src/styles/tokens.css                 CSS custom properties
    ├──► src/styles/_variables.scss            SCSS variables (opt-in via output.scssVars)
    ├──► src/styles/fonts.css                  @font-face declarations
    ├──► src/styles/base-styles.scss           Base typography (zero-specificity)
    │
    ├──► dist/wp/theme-{prefix}.json           WordPress settings + styles
    ├──► dist/wp/tokens.wp.css                CSS vars mapped to --wp--preset--*
    ├──► dist/wp/tokens.css                   CSS vars with hardcoded values
    └──► dist/wp/integrate.php                PHP hooks for the theme.json cascade

Your components always reference --prefix--* CSS variables. In Storybook, those resolve to hardcoded values. In WordPress, they can optionally map to --wp--preset--* variables so themes can override them via the Site Editor.

Key Concepts

  • Single source of truth — One config drives all outputs. Change a color once, it updates everywhere.
  • 12 token categories — Colors, gradients, spacing, font families, font sizes, shadows, layout, font weights, line heights, border radii, transitions, and z-index.
  • Locked vs themeable — By default, tokens are hardcoded (locked). Set output.themeable: true to let WordPress themes override them.
  • Zero-specificity base styles — Generated SCSS uses :where() selectors so component BEM classes always win over base typography.
  • Storybook preset — Auto-injects all generated styles into Storybook. No manual imports.
  • WordPress default layer — The generated theme.json injects at the lowest priority layer, so any theme can override it.

Getting Started

1. Install

npm install @troychaplin/component2block --save-dev

2. Create the config

npx c2b init

This creates c2b.config.json with sensible defaults. Edit it to match your project — at minimum, set the prefix to your library's namespace.

3. Generate

npx c2b generate

4. Add to your build

Add a script so tokens regenerate as part of your dev and build pipeline:

{
  "scripts": {
    "c2b": "c2b generate",
    "dev": "npm run c2b && storybook dev -p 6006",
    "build": "npm run c2b && npm run build:lib && npm run build:css"
  }
}

Quick Example

{
  "prefix": "mylib",
  "tokens": {
    "color": {
      "primary": "#0073aa",
      "primary-hover": { "value": "#005a87", "cssOnly": true }
    },
    "fontSize": {
      "small": { "min": "0.875rem", "max": "1rem" }
    }
  }
}
npx c2b generate

Then in your components:

.mylib-card {
  color: var(--mylib--color-primary);
  font-size: var(--mylib--font-size-small);
}

CLI

npx c2b <command> [options]

Commands:
  init              Create a c2b.config.json from the example template
  generate          Read config and generate all output files
  help              Show this help message

Options (generate):
  --config <path>   Path to config file (default: ./c2b.config.json)
  --dry-run         Output to stdout instead of writing files

Programmatic API

import { generate } from '@troychaplin/component2block';

const result = generate('./c2b.config.json');
// result.files: Array<{ path: string; size: number }>

Individual generators, config helpers, and types are also exported:

import {
  // Config
  loadConfig,
  validateConfig,
  // Generators
  generateTokensCss,
  generateTokensScss,
  generateTokensWpCss,
  generateThemeJson,
  generateFontsCss,
  generateContentScss,
  generateIntegratePhp,
  copyFontFiles,
  // Types
  type C2bConfig,
  type C2bConfigInput,
  type TokenEntry,
  type TokenGroup,
  type TokenCategory,
  type FontFaceEntry,
  type BaseStylesConfig,
} from '@troychaplin/component2block';

Documentation

Getting Started — Install, configure, and generate

Configuration Reference

| Guide | Description | |-------|-------------| | Overview | Global fields, token categories, generated files, and full example | | Colors & Gradients | Color palette, gradients, cssOnly tokens, and locked vs themeable mode | | Spacing | Spacing scale, WordPress slug conventions, and responsive values | | Shadows | Box shadows, preset vs custom behavior, and Site Editor integration | | Fonts | Static fonts, variable fonts, Google Fonts, and file placement | | Base Styles | Elements, typography, colors, spacing, and :where() selectors |

Guides

| Guide | Description | |-------|-------------| | Tokens | Token syntax, categories, fluid fonts, CSS output | | Markup Patterns | Layout classes for Storybook and WordPress | | Storybook Preset | Auto-injecting generated styles into Storybook | | CLI & Build | CLI commands, build scripts, local-link testing, and publishing |

WordPress

| Guide | Description | |-------|-------------| | Integration | Adding compiled assets to a WordPress block theme | | Theming | Locked vs themeable mode, overrides, style variations | | Blocks | Block plugin setup and component registration | | Editor Styles | Loading styles inside the block editor iframe | | theme.json Reference | Full settings and styles structure |

Advanced

| Guide | Description | |-------|-------------| | Architecture | Design decisions, project structure, category registry | | Token Flow | How tokens resolve differently per output |

Development

npm install
npm run build    # Compile TypeScript
npm test         # Run the test suite

Screenshots

| Before | After | |-------|-------------| | | | | | | | | | | | |