hextimator
v0.13.0
Published
Runtime theming for multi-tenant apps.
Downloads
3,251
Maintainers
Readme
hextimator
Runtime theming for multi-tenant apps.
Your customers pick a brand color. Your app looks good every time. No per-customer design reviews. No manual tuning. Yellow does not break your UI.
Each call takes under a millisecond (~0.4ms [^perf]). Same color and options always produce the same tokens. Run it on the request path. Cache it if you want.
~12 kB min+gzip. Zero dependencies.
Try it: hextimator.com
Why hextimator exists
You ship a B2B, B2B2C, or white-label app. Every tenant brings a brand color. Your choices today:
- Let them pick any hex. Legal-pad yellow buttons become unreadable. Cheeto tangerine toasts look like your warning state.
- Curate a palette. You tell a paying customer their brand color is not allowed.
hextimator is the third option. One color in, whole theme out. Light and dark. Semantic roles and surfaces. Foregrounds meet WCAG contrast by default (AAA unless you opt down). Even yellow.
How it compares
hextimator is not the first palette generator. It targets one job the others skip: arbitrary brand colors at runtime.
- Adobe Leonardo Runtime contrast scales from arbitrary hex (
Theme→contrastColors, target ratios). A construction kit: you wire roles, surfaces, and dark mode yourself. hextimator is one call with those built in. - Material dynamic color Full theming from one seed color. Battle-tested on Android. Output follows Material's token scheme. Hard to use outside Material-shaped UIs.
- Radix Colors Hand-tuned scales with strong semantics. Fixed curated set. Does not generate themes from arbitrary input.
- tints.dev / uicolors.app Quick Tailwind shade scales from one color. Build-time only. No semantic roles, contrast guarantees, dark theme, or library API.
- culori / chroma.js Color math and conversions. You build a generator with these. They are not generators.
Hand-crafting one brand's design system? Several of these beat hextimator. Color comes from user input (tenants, white-label customers, CMS authors)? That is hextimator's job.
Installation
npm i hextimatorTailwind v4: import hextimator/tailwind.css in your CSS entry (see Tailwind).
30-second integration
import { hextimate } from "hextimator";
const css = hextimate("#C0FFEE").format({ as: "css" });hextimate turns one color into a theme. You choose how to ship it: inline <style>, a .css file, a template partial, an edge cache, or something else. For tokens instead of a stylesheet, use format({ as: 'object' }).
No DOM. Pure computation. Works with SSR.
React (SSR-safe)
import { HextimatorStyle } from "hextimator/react";
<HextimatorStyle color={"#0FF1CE"} />;Put it in your layout <head>. Server render writes a <style> node. No useEffect. No FOUC when you pair it with static HTML. API and dark mode: React.
CLI (and AI agents)
Same engine as the library. Flags for presets and format.
npx hextimator '#BADA55' --preset shadcn # framework-shaped tokens
npx hextimator '#BADA55' --preset muted # style preset
npx hextimator '#BADA55' --preset vibrant
npx hextimator '#BADA55' --preset boldWhat is in every theme
| Role | Variants | | -------- | --------------------------------- | | surface | DEFAULT, strong, weak, foreground | | accent | DEFAULT, strong, weak, foreground | | positive | DEFAULT, strong, weak, foreground | | negative | DEFAULT, strong, weak, foreground | | caution | DEFAULT, strong, weak, foreground |
Plus brand-exact (your input color, unchanged) and brand-exact-foreground.
Customization and reference
- Customization: style and format options
- Extending the palette:
addRole,addVariant,addToken - Presets: shadcn/ui configs and custom presets
- Multiple themes: dynamic theming and
.fork() - React: hook,
HextimatorStyle, provider, scoped themes, dark mode - Tailwind CSS v4: setup and usage
Also
Contrast methodology
WCAG 2.x contrast ratios. AAA by default. Opt down with minContrastRatio. Audits and compliance tooling still measure this way.
APCA is the perceptual model in draft WCAG 3. Better for a lot of UI. Not what pass/fail checks ask for yet. Optional support is planned when WCAG 3 settles.
Stability
The API follows strict semver. Builder methods, options, formats, CLI flags, and token names only break in majors, with notes in migration.md.
Generated color values are a separate contract. Output is fully deterministic: same version, same color, same options, same tokens. The algorithm itself may improve in minors (wider hue ranges, better anchors), which changes the exact values a theme produces. Every such change is flagged in the changelog with how to opt back into the old behavior.
In practice:
- Pin an exact version if you cache or snapshot generated output.
- Patches only change generated values to fix bugs.
- Contrast guarantees hold across all releases. Whatever changes, foregrounds meet your configured minimum against their backgrounds.
Contributing
Open issues and PRs at github.com/fgrgic/hextimator.
[^perf]: Measured on Apple Silicon M2 Max with Bun. Ballpark only. Your hardware and runtime will differ.
