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

salt-theme-gen

v1.3.1

Published

One color → 150+ design tokens. OKLCH-based theme generator with CSS variables, Tailwind config, DTCG export, APCA contrast, tonal palettes, and color blindness simulation. Zero deps, strict TypeScript.

Readme

salt-theme-gen

One color. 150+ design tokens. Light + dark. Accessible by default.

Give it a hex color — or pick one of 20 curated presets. Get back a complete, mathematically correct design system: semantic colors, tonal palettes, interactive states, surface elevations, spacing, radius, font sizes, CSS custom properties, Tailwind config, DTCG tokens, WCAG and APCA contrast reports, and color blindness simulation. All from a single function call.

const theme = generateTheme({ primary: '#0E9D8E' });

Built on OKLCH — the perceptually uniform color space that makes hue shifts, dark mode, and harmony actually look right. Not HSL. Not sRGB math. OKLCH.

Zero dependencies. Pure TypeScript. Strict types throughout. Works in React Native, React, Next.js, Vue, Svelte, Angular, Node, Bun, Deno — or any JavaScript runtime.

npm license TypeScript

Full documentation → learn.esalt.net/salt-theme-gen

Formerly react-native-salt-theme-gen. If you're upgrading, just change your import — the API is identical.


Install

npm install salt-theme-gen

Quick Start

import { generateTheme } from 'salt-theme-gen';

const theme = generateTheme({ primary: '#0E9D8E' });
// or
const theme = generateTheme({ preset: 'ocean' });

theme.light and theme.dark each contain:

  • 21 semantic colorsprimary, onPrimary, background, surface, text, danger, success
  • 32 state colors — hover, pressed, focused, disabled for all 8 intents
  • 4 surface elevation levels — card, elevated, modal, popover
  • 88 tonal palette steps — 11-step scales for all 8 intent colors
  • Spacing, radius, font size scales — 7 steps each
  • WCAG accessibility report — 18 pre-computed contrast checks
  • APCA contrast report — 25 perceptual contrast checks

CSS Custom Properties

import { generateCssVariables } from 'salt-theme-gen';

const { css } = generateCssVariables(theme, { format: 'both' });
// → ready-to-inject stylesheet
// → hex fallback + @supports oklch() for modern browsers
// → 150+ --salt-* custom properties
/* Generated output */
:root {
  --salt-color-primary: #0077dc;
  --salt-color-background: #f5f8ff;
  --salt-palette-primary-500: #3a7ec8;
  --salt-state-primary-hover: #0068c4;
  --salt-spacing-md: 12px;
  --salt-radius-pill: 9999px;
  /* ... 150+ tokens */
}
[data-theme='dark'] { --salt-color-primary: #459af9; /* ... */ }
@supports (color: oklch(0 0 0)) { /* oklch values for modern browsers */ }

Options: format ('hex' | 'oklch' | 'both'), lightSelector, darkSelector.


Tailwind CSS

import { generateTailwindConfig } from 'salt-theme-gen';

const { extend } = generateTailwindConfig(theme);
// Spread into tailwind.config.ts → theme.extend
<!-- All tokens as utility classes -->
<button class="bg-salt-primary text-salt-on-primary rounded-salt-md px-salt-lg">
  Save
</button>

Tonal Palettes

// Already in the theme output
theme.light.palettes.primary[50]   // lightest tint
theme.light.palettes.primary[500]  // mid-range
theme.light.palettes.danger[700]   // dark red — readable on light backgrounds

// Generate for any arbitrary color
import { generateTonalPalette } from 'salt-theme-gen';
const palette = generateTonalPalette('#0f4c81');

DTCG Token Export

import { generateDtcgTokens } from 'salt-theme-gen';

const { json } = generateDtcgTokens(theme);
// W3C Design Tokens format — works with Style Dictionary 4, Token Studio, Theo

Color Blindness Simulation

import { simulateTheme, simulateColorBlindness } from 'salt-theme-gen';

// Simulate an entire theme
const sim = simulateTheme(theme, 'deuteranopia');
// → new GeneratedTheme with all colors shifted + accessibility reports recomputed

// Simulate a single color
const shifted = simulateColorBlindness('#e63946', 'protanopia');

7 types: protanopia, deuteranopia, tritanopia, protanomaly, deuteranomaly, tritanomaly, achromatopsia.


APCA Contrast

import { apcaContrast, meetsAPCA } from 'salt-theme-gen';

const lc = Math.abs(apcaContrast('#0077dc', '#f5f8ff'));
// → 62.4 (Lc value)

meetsAPCA('#0077dc', '#f5f8ff', 60);
// → true (Lc ≥ 60)

// Already computed in every theme:
theme.light.apca.textOnBackground;
// → { lc: 94.2, level: 'Lc75' }

Color Presets (20)

peacock · ocean · forest · sunset · cherry-blossom · arctic · desert · lavender · emerald · coral-reef · midnight · autumn · rose-gold · sapphire · mint · volcano · twilight · honey · storm · aurora


Scale Presets

| Scale | Options | | --- | --- | | spacing | compact · default · relaxed · spacious | | radius | sharp · default · rounded · pill | | fontSize | small · default · large · editorial |

Or pass a custom scale object for full control.


Color Harmony

generateTheme({ primary: '#1e90ff', harmony: 'complementary' });

analogous (default) · complementary · triadic · split-complementary · tetradic · monochromatic


Post-generation Tweaks

import { adjustTheme, diffTheme } from 'salt-theme-gen';

// Fine-tune without losing the system
const tweaked = adjustTheme(theme, {
  light: { colors: { primary: '#0052cc' } },
  both: { spacing: { md: 14 } },
});

// Compare two themes
const diff = diffTheme(theme, tweaked);
console.log(diff.light.colors?.primary); // { old: '#0077dc', new: '#0052cc' }

Validation

import { parseThemeJSON } from 'salt-theme-gen';

// Safely parse from AsyncStorage, API response, or localStorage
const theme = parseThemeJSON(JSON.parse(stored));
// Throws with descriptive path on invalid input:
// "theme.dark.states.warning.disabled: expected hex color string"

All Exports

Functions

| Function | Description | |----------|-------------| | generateTheme | Main entry point — one color → full theme | | generateCssVariables | CSS custom properties (hex / oklch / both) | | generateTailwindConfig | Tailwind theme.extend object | | generateDtcgTokens | W3C Design Tokens (DTCG) export | | generateTonalPalette | 11-step tonal scale for any color | | generateTonalPalettes | All 8 tonal palettes from a theme | | simulateTheme | Full theme color blindness simulation | | simulateColorBlindness | Single color color blindness simulation | | adjustTheme | Post-generation token overrides | | diffTheme | Structured comparison of two themes | | parseThemeJSON | Runtime validation for deserialized themes | | deriveColors | 21 semantic colors from a primary | | deriveSurfaceElevation | 4 elevation levels | | resolveHarmonyAccents | Hue offsets for harmony strategies | | deriveOnColor | WCAG AA foreground for a background | | autoCorrectContrast | Adjust foreground to meet contrast ratio | | buildAPCAReport | APCA report from color set | | deriveStateColors | hover/pressed/focused/disabled for one color | | deriveAllIntentStates | States for all 8 intents | | apcaContrast | Signed APCA Lc value | | meetsAPCA | Boolean APCA threshold check | | parseColor | HEX / RGB / CSS name → normalized hex | | hexToOklch · oklchToHex | OKLCH ↔ hex | | hexToRgb · rgbToHex | RGB ↔ hex | | relativeLuminance · contrastRatio | WCAG math | | meetsWcagAA · meetsWcagAALarge | WCAG threshold checks | | darken · lighten · desaturate | OKLCH color manipulation | | adjustHue · setLightness · setChroma | OKLCH channel adjustment | | mix | OKLCH blend with shortest-arc hue | | isValidHex · normalizeHex · gamutClamp | Utilities |

Types

GeneratedTheme · GeneratedThemeMode · GenerateThemeOptions · SemanticColors · StateColors · IntentStates · SurfaceElevation · TonalPalette · TonalPalettes · TonalPaletteKey · TonalStep · AccessibilityReport · ContrastEntry · APCAReport · APCAEntry · APCALevel · CssFormat · CssVariablesOptions · CssVariablesResult · TailwindThemeExtend · TailwindConfigResult · DtcgToken · DtcgColorToken · DtcgDimensionToken · DtcgGroup · DtcgTokensResult · ColorBlindnessType · ColorHarmony · ThemePreset · SpacingPreset · FontSizePreset · RadiusPreset · SpacingScale · RadiusScale · FontSizeScale · ThemeOverrides · ThemeModeOverrides · ThemeDiff · ThemeModeDiff · FieldChange<T> · DeriveColorsOptions · HarmonyAccents · RGB · OKLCH · Oklab

Constants

NATURE_PRESETS · SPACING_PRESETS · RADIUS_PRESETS · FONT_SIZE_PRESETS


Use with react-native-salt

import { SaltProvider } from '@esaltws/react-native-salt';
import { generateTheme } from 'salt-theme-gen';

const theme = generateTheme({ preset: 'forest' });

export default function App() {
  return (
    <SaltProvider lightTheme={theme.light} darkTheme={theme.dark}>
      {/* Your app */}
    </SaltProvider>
  );
}

Full guides, integration examples, and API reference → learn.esalt.net/salt-theme-gen

License

MIT