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

@themeshift/vite-plugin

v0.4.0

Published

Vite plugin wrapper for ThemeShift core token tooling.

Readme

@themeshift/vite-plugin

License: MIT Build Coverage npm

ThemeShift is a Vite plugin that makes working with Style Dictionary easy as pie 🥧

Migration note: this package was renamed from @themeshift/vite-plugin-themeshift to @themeshift/vite-plugin.

It watches your token files, rebuilds generated outputs, and gives you a simple token() helper for Sass. It can also start from tokens published by a UI package and layer app-level overrides on top.

This package lives inside the ThemeShift monorepo. Use the repo root for local development and apps/ui-app to test the full flow with @themeshift/ui.

What it does

  • Watches tokens/**/*.json
  • Builds CSS variables, Sass tokens, and token manifests
  • Supports light, dark, and optional print themes
  • Injects a global Sass token() helper
  • Ships a standalone Sass and JavaScript token module
  • Lets apps extend tokens from installed packages such as @themeshift/ui

Quick start

Install the package and the tools it needs:

npm install --save-dev @themeshift/vite-plugin sass

Add the plugin to vite.config.ts:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { themeShift } from '@themeshift/vite-plugin';

export default defineConfig({
  plugins: [react(), themeShift()],
});

Create tokens/theme.json:

{
  "theme": {
    "text": {
      "base": { "$value": "#0f172a" }
    }
  }
}

Import the generated CSS:

import './css/tokens.css';

By default, ThemeShift writes:

  • src/css/tokens.css
  • src/sass/_tokens.static.scss
  • src/design-tokens/token-paths.{json,ts}
  • src/design-tokens/token-values.{json,ts}

Common Sass usage

ThemeShift injects a global token() helper by default, so this works in app styles:

.button {
  color: token('text.primary');
}

If you prefer an explicit import, use the published Sass module:

@use '@themeshift/vite-plugin/token' as themeShift;

.button {
  color: themeShift.token('text.primary');
}

If you use cssVarPrefix, you can pass it per call:

@use '@themeshift/vite-plugin/token' as themeShift;

.button {
  color: themeShift.token('components.button.font', 'themeshift');
}

For shared mixins and partials, prefer the namespaced import:

@use '@themeshift/vite-plugin/token' as themeShift;

@mixin text-style($path) {
  font: themeShift.token('typography.styles.#{$path}.font');
}

JavaScript helpers

ThemeShift ships a JavaScript helper on the same ./token path.

Use token() to read the current CSS variable value in the browser:

import { token } from '@themeshift/vite-plugin/token';

const textColor = token('text.primary', { prefix: 'themeshift' });

Use tokenValue() to read a value from the generated token manifest:

import { tokenValue } from '@themeshift/vite-plugin/token';
import { tokenValues } from './design-tokens/token-values';

const titleStyle = tokenValue('text.style.title', { values: tokenValues });

Color functions

ThemeShift also provides functions for modifying colours.

Supported functions:

  • mix(color1, color2, amount)
  • lighten(color, amount)
  • darken(color, amount)
  • alpha(color, amount)

Example:

{
  "components": {
    "button": {
      "light": {
        "intents": {
          "primary": {
            "bg": { "$value": "{color.blue.400}" },
            "hover": { "$value": "lighten({color.blue.300}, 0.1)" },
            "pressed": { "$value": "darken({color.blue.500}, 0.1)" }
          }
        }
      }
    }
  }
}

amount must be between 0 and 1.

Hybrid token nodes

ThemeShift supports token nodes with both a main value and nested child token values. This is useful for state tokens such as bg.hover and fg.disabled.

Example:

{
  "components": {
    "button": {
      "light": {
        "intents": {
          "primary": {
            "bg": {
              "$value": "{color.blue.400}",
              "hover": { "$value": "{color.blue.300}" },
              "disabled": { "$value": "alpha({color.blue.300}, 0.3)" }
            },
            "fg": {
              "$value": "{color.blue.400.text}",
              "disabled": { "$value": "alpha({color.blue.400.text}, 0.5)" }
            }
          }
        }
      }
    }
  }
}

This gives you token paths like:

  • components.button.light.variant.primary.background
  • components.button.light.variant.primary.background.hover
  • components.button.light.variant.primary.text
  • components.button.light.variant.primary.text.disabled

Theme modes

To support theme modes, split your token files by theme:

tokens/theme.light.json

{
  "theme": {
    "light": {
      "text": {
        "base": { "$value": "#0f172a" }
      },
      "surface": {
        "base": { "$value": "#ecf0f1" }
      }
    }
  }
}

tokens/theme.dark.json

{
  "theme": {
    "dark": {
      "text": {
        "base": { "$value": "#e2e8f0" }
      },
      "surface": {
        "base": { "$value": "#2c3e50" }
      }
    }
  }
}

Then set data-theme on the document root:

<html lang="en" data-theme="dark">
  ...
</html>

Plugin options

These are the options most apps use.

extends

Use extends to load token files from an installed package before local tokens. Local files still win.

Simple example:

themeShift({
  extends: ['@themeshift/ui'],
  cssVarPrefix: 'themeshift',
});

Explicit package config:

themeShift({
  extends: [
    {
      package: '@themeshift/ui',
      tokensGlob: 'dist/tokens/**/*.json',
    },
  ],
});

cssVarPrefix

Use cssVarPrefix to prefix generated CSS variables.

themeShift({
  cssVarPrefix: 'themeshift',
});

This changes:

  • --components-button-font
  • to --themeshift-components-button-font

groups

Use groups to control comment sections in generated tokens.css.

themeShift({
  groups: [
    { label: 'Colors', match: (name) => name.startsWith('color-') },
    { label: 'Theme', match: (name) => name.startsWith('theme-') },
    { label: 'Components', match: (name) => name.startsWith('components-') },
    { label: 'Other', match: () => true },
  ],
});

defaultTheme

Use defaultTheme when you want one theme copied into plain :root as a fallback.

themeShift({
  defaultTheme: 'light',
});

outputPrintTheme

Set outputPrintTheme: true if you want print theme output.

themeShift({
  outputPrintTheme: true,
});

outputComments

Set outputComments: true to include token descriptions in generated CSS and Sass.

themeShift({
  outputComments: true,
});

Example token:

{
  "space": {
    "4": {
      "$value": "1rem",
      "$description": "16px"
    }
  }
}

filters

Use filters to choose which tokens are written to each output.

themeShift({
  filters: {
    scss: {
      includePrefixes: ['radius-', 'spacing-', 'font-', 'text-', 'layout-'],
      excludePrefixes: ['theme-', 'components-'],
    },
  },
});

You can also use a function:

themeShift({
  filters: {
    scss: (token) => !token.attributes?.theme,
  },
});

reloadStrategy

Use reloadStrategy: 'full' if you want a full page reload instead of HMR when token files change.

themeShift({
  reloadStrategy: 'full',
});

log

Use log to show or hide Style Dictionary output.

Show warnings:

themeShift({
  log: { warnings: 'warn' },
});

Keep output quiet:

themeShift({
  log: { verbosity: 'silent', warnings: 'disabled' },
});

Playground

This repo includes a small playground in playground/.

npm install
npm -C playground install
npm run playground

Development

Run the package in watch mode:

npm run dev

Build the package:

npm run build

License

MIT