Skip to content

SDK for managing design tokens (colors, typography, spacing) across React/Vue/Angular projects.

License

Notifications You must be signed in to change notification settings

M1tsumi/Theme-Kit

Repository files navigation

ThemeKit

Design tokens shouldn't be scattered across your codebase. ThemeKit gives you one place to define colors, typography, spacing—everything—and use them anywhere. React, Vue, Angular, vanilla JS. Doesn't matter.

Why ThemeKit?

If you've ever had to update a primary color in 47 different files, you know the pain. ThemeKit fixes that. Define your tokens once, use them everywhere, switch themes on the fly.

What you get:

  • Works with React, Vue, Angular, or plain JavaScript
  • Full TypeScript support (types are auto-generated)
  • Light/dark mode with persistence built in
  • CLI to spit out CSS variables, SCSS, TypeScript—whatever you need
  • Validation so your tokens stay consistent
  • Runtime alias resolution with circular reference protection (opt-in)
  • Prefetch + cache themes so switches stay instant

Install

npm install @quefep/theme-kit

Getting Started

1. Set up your tokens

Create a tokens.json (you can also pass a JS object or a map of theme names ➝ tokens straight into the config):

{
  "colors": {
    "primary": "#4A90E2",
    "secondary": "#50E3C2",
    "background": "#FFFFFF",
    "text": "#333333"
  },
  "typography": {
    "fontFamily": "Inter, sans-serif",
    "fontSize": {
      "sm": "12px",
      "md": "16px",
      "lg": "20px"
    }
  },
  "spacing": {
    "sm": "4px",
    "md": "8px",
    "lg": "16px"
  }
}

2. Initialize

import { ThemeKit } from '@quefep/theme-kit';
import tokens from './tokens.json';

const theme = new ThemeKit({
  defaultTheme: 'light',
  tokens,
});

3. Use it in your framework

React:

import { ThemeProvider, useTheme } from '@quefep/theme-kit/react';

function App() {
  return (
    <ThemeProvider theme={theme}>
      <MyButton />
    </ThemeProvider>
  );
}

function MyButton() {
  const { getToken } = useTheme();
  return (
    <button style={{ backgroundColor: getToken('colors.primary') }}>
      Click me
    </button>
  );
}

Vue:

import { createApp } from 'vue';
import { ThemeKitPlugin } from '@quefep/theme-kit/vue';

createApp(App).use(ThemeKitPlugin, { theme });
<template>
  <button :style="{ backgroundColor: primaryColor }">Click me</button>
</template>

<script setup>
import { useColor } from '@quefep/theme-kit/vue';
const primaryColor = useColor('primary');
</script>

Angular:

import { ThemeKitModule } from '@quefep/theme-kit/angular';

@NgModule({
  imports: [ThemeKitModule.forRoot({ theme })],
})
export class AppModule {}

Vanilla JS:

import { ThemeKit, createVanillaThemeKit } from '@quefep/theme-kit/vanilla';

const theme = new ThemeKit({ tokens });
const vanillaTheme = createVanillaThemeKit(theme);

document.body.style.backgroundColor = vanillaTheme.getColor('background');

Switching Themes

// Switch to dark mode
theme.switch('dark');

// Or pass custom tokens on the fly
theme.switch('custom', {
  colors: {
    primary: '#FF6B6B',
    background: '#1A1A1A',
  },
});

// Check what's active
console.log(theme.getCurrentTheme()); // 'dark'

In React:

function ThemeToggle() {
  const { currentTheme, switchTheme } = useTheme();
  
  return (
    <button onClick={() => switchTheme(currentTheme === 'light' ? 'dark' : 'light')}>
      {currentTheme === 'light' ? 'Go dark' : 'Go light'}
    </button>
  );
}

Token Aliases (v2.0.0 Enhanced)

Reference other tokens using curly braces. ThemeKit v2.0.0 adds powerful new aliasing capabilities:

{
  "colors": {
    "blue500": "#4A90E2",
    "primary": "{colors.blue500}",
    "secondary": "{dark:colors.primary}",
    "lighter": "{colors.primary + 20}",
    "darker": "{colors.primary * 0.8}"
  }
}

New v2.0.0 Features:

  • Lazy Resolution: Resolve aliases only when accessed for better performance
  • Cross-Theme References: Use {theme:path} to reference tokens from other themes
  • Runtime Expressions: Simple arithmetic operations in aliases

Enable enhanced runtime aliasing:

const theme = new ThemeKit({
  tokens,
  aliasing: {
    enabled: true,
    lazy: true,              // Resolve on-demand (faster startup)
    allowCrossTheme: true,   // Reference other themes
    allowExpressions: true,  // Arithmetic operations
    maxDepth: 15,
  },
});

Prefetch & Cache Themes

ThemeKit now caches resolved tokens and lets you warm them up ahead of time:

theme.prefetchThemes();          // prefetch everything
theme.prefetchThemes(['dark']);  // or target a subset

Combine this with the built-in cache to keep theme switches snappy even with massive token graphs.

Color Utilities

Built-in functions for color manipulation:

import { lighten, darken, alpha, mix, contrastRatio, readableOn } from '@quefep/theme-kit';

lighten('#4A90E2', 20);        // 20% lighter
darken('#4A90E2', 20);         // 20% darker
alpha('#4A90E2', 0.5);         // rgba with 50% opacity
mix('#4A90E2', '#FF6B6B', 50); // 50/50 blend
contrastRatio('#000', '#fff'); // WCAG contrast ratio
readableOn('#4A90E2');         // returns black or white for text

CLI

Generate token files in different formats:

# CSS variables
npx @quefep/theme-kit generate --format css

# SCSS with custom prefix
npx @quefep/theme-kit generate --format scss --prefix myapp

# TypeScript types
npx @quefep/theme-kit generate --format ts

# Resolve aliases before generating
npx @quefep/theme-kit generate --format css --resolve-aliases

# Validate your tokens
npx @quefep/theme-kit validate

# Compare two token files
npx @quefep/theme-kit diff tokens-v1.json tokens-v2.json

# Start a new project
npx @quefep/theme-kit init --template basic

CSS output looks like:

:root {
  --tk-colors-primary: #4A90E2;
  --tk-colors-secondary: #50E3C2;
  --tk-colors-background: #FFFFFF;
  --tk-colors-text: #333333;
  --tk-typography-fontFamily: Inter, sans-serif;
  --tk-spacing-sm: 4px;
  --tk-spacing-md: 8px;
  --tk-spacing-lg: 16px;
}

Configuration

Drop a themekit.config.js in your project root:

module.exports = {
  tokens: './tokens.json',
  defaultTheme: 'light',
  aliasing: {
    enabled: true,
    maxDepth: 10,
  },
  persistence: {
    enabled: true,
    key: 'themekit-theme',
    storage: 'localStorage',
  },
  validation: {
    enabled: true,
    strict: false,
    rules: [
      {
        name: 'naming-convention',
        pattern: /^[a-z][a-zA-Z0-9-_]*$/,
        message: 'Use camelCase or kebab-case for token names',
        severity: 'warning',
      },
      {
        name: 'color-format',
        pattern: /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$|^rgb\(|^rgba\(/,
        message: 'Colors should be hex, rgb, or rgba',
        severity: 'error',
      },
    ],
  },
};

API

ThemeKit

const theme = new ThemeKit(config);

theme.registerTheme({ name: 'dark', tokens: {...} });
theme.switch('dark');
theme.getCurrentTheme();      // 'dark'
theme.getCurrentTokens();     // { colors: {...}, ... }
theme.getToken('colors.primary');
theme.getAvailableThemes();   // ['light', 'dark']
theme.prefetchThemes();       // Warm up caches for one or more themes
theme.addThemeChangeListener((name, tokens) => { ... });
theme.validateTokens(tokens); // { valid: true, errors: [] }

React Hooks

  • useTheme() — full theme context
  • useToken(path) — grab a specific token
  • useColor(name) — shorthand for colors
  • useTypography(name) — typography tokens
  • useSpacing(name) — spacing tokens

Vue Composables

Same deal: useThemeKit(), useToken(), useColor(), useTypography(), useSpacing()

Angular

Inject ThemeKitService and call switchTheme(), getToken(), etc.

Project Structure

src/
├── core/      # The main ThemeKit class
├── types/     # TypeScript definitions
├── react/     # React bindings
├── vue/       # Vue bindings
├── angular/   # Angular bindings
├── vanilla/   # Vanilla JS adapter
└── cli/       # CLI commands

Tips

  • Keep tokens atomic (e.g., blue-500) rather than semantic (e.g., button-background)
  • Version control your token files
  • Run validation in CI so bad tokens don't slip through
  • Generate static CSS for production when you can

What's Next

  • Svelte and SolidJS adapters
  • Figma/Sketch sync
  • Multi-brand support
  • Visual token editor

Contributing

git clone https://github.com/M1tsumi/Theme-Kit.git
cd Theme-Kit
npm install
npm run dev

Run tests with npm test, build with npm run build.

License

MIT

About

SDK for managing design tokens (colors, typography, spacing) across React/Vue/Angular projects.

Resources

License

Stars

Watchers

Forks

Packages

No packages published