The styling engine built for design systems
Deterministic CSS generation. State‑aware DSL. Zero specificity conflicts. Ever.
Why Tasty
Everything you need for styling at scale
Deterministic at Any Scale
Exclusive selector generation eliminates the entire class of cascade and specificity bugs. Refactor freely.
DSL That Feels Like CSS
Property names you already know with syntax sugar that removes boilerplate. Learn in minutes, not days.
Design‑System Native
Color tokens, spacing units, typography presets, and recipes are first‑class primitives, not afterthoughts.
State‑Aware Styling
Media queries, container queries, @supports, :has() — all compose in one declarative state map.
Sub‑Element Styling
Style inner elements from the parent definition. No extra components, no CSS leakage.
SSR & Zero‑Runtime
Runtime, zero‑runtime, or SSR with zero‑cost hydration. Same DSL, same tokens, same output.
How It Actually Works
Every state mapping compiles into mutually exclusive selectors
Tasty DSL
Inputconst Button = tasty({
as: 'button',
styles: {
fill: {
'': '#purple',
':hover': '#purple-04',
':active': '#purple-05',
},
color: '#white',
padding: '1.5x 3x',
radius: 'round',
border: 'none',
cursor: 'pointer',
transition: 'theme',
},
});Exclusive CSS Selectors
Output/* Default: not hovered and not active */
.t0.t0:not(:hover):not(:active) {
background: var(--purple-color);
}
/* Hovered but not active */
.t0.t0:hover:not(:active) {
background: var(--purple-04-color);
}
/* Active */
.t0.t0:active {
background: var(--purple-05-color);
}
/* Base styles (always applied) */
.t0.t0 {
color: white;
padding: 12px 24px;
border-radius: 9999px;
border: none;
cursor: pointer;
transition: all var(--transition-duration)
var(--transition-timing-function);
}Tasty DSL
Input// Define a reusable state alias
configure({
states: {
'@dark': '@root(schema=dark) | (!@root(schema) & @media(prefers-color-scheme: dark))',
},
});
// Use the alias in styles
const Text = tasty({
// You can also define `@dark` here
styles: {
color: {
'': '#text',
'@dark': '#text-on-dark',
},
},
});Exclusive CSS Selectors
Output/* Branch 1: Explicit dark schema */
:root[data-schema="dark"] .t0.t0 {
color: var(--text-on-dark-color);
}
/* Branch 2: No schema attribute + OS prefers dark */
@media (prefers-color-scheme: dark) {
:root:not([data-schema]) .t0.t0 {
color: var(--text-on-dark-color);
}
}
/* Default: no schema + OS does not prefer dark */
@media (not (prefers-color-scheme: dark)) {
:root:not([data-schema="dark"]) .t0.t0 {
color: var(--text-color);
}
}
/* Default: schema is set but not dark */
:root:not([data-schema="dark"])[data-schema] .t0.t0 {
color: var(--text-color);
}No two rules can match at the same time. No specificity arithmetic. No source‑order dependence.
Components compose and extend without collisions.
Design Token Support
Specify spacing, typography, and WCAG‑compliant color palettes with a unified token system
useGlobalStyles('body', {
// Base tokens
'$gap': '8px',
'$radius': '10px',
'$card-radius': '20px',
'$border-width': '1px',
'$outline-width': '2px',
'$bold-font-weight': 600,
'$transition': '0.2s',
'$content-width': '1200px',
// Color tokens (OKHSL)
'#success': 'okhsl(145 75% 55%)',
'#warning': 'okhsl(70 80% 60%)',
'#danger': 'okhsl(25 85% 55%)',
'#info': 'okhsl(215 70% 55%)',
'#neutral': 'okhsl(210 10% 50%)',
});const violet = glaze(272, 75);
violet.colors({
surface: {
lightness: 98, saturation: 0.2,
},
text: {
base: 'surface', lightness: '-62',
contrast: 'AAA', saturation: 0.08,
},
'accent-surface': {
lightness: 52, mode: 'fixed',
},
'shadow-md': {
type: 'shadow', bg: 'surface',
fg: 'text', intensity: 12,
},
});Tasty natively supports OKHSL — a perceptually uniform color space where equal steps in lightness produce equal changes in perceived contrast, making palette generation predictable by design.
Need full color palettes with automatic dark mode, high‑contrast schemes, and WCAG‑compliant contrast ratios? Use Glaze — a zero‑dependency companion library that generates production‑ready color palettes.
See It In Action
Real patterns from production codebases
State Maps
Style any property based on pseudo‑classes, data attributes, media queries, and more.
const Button = tasty({
as: 'button',
styles: {
fill: {
'': '#primary-accent-surface',
':hover': '#primary-icon',
':active': '#primary-text',
'[disabled]': '#primary-disabled',
},
cursor: {
'': 'pointer',
'[disabled]': 'not-allowed',
},
transition: 'theme',
},
});Responsive Design
Define breakpoints once, use @mobile and @tablet as states anywhere.
configure({
states: {
'@tablet': '@media(640px <= w < 1024px)',
'@mobile': '@media(w < 640px)',
},
});
const Layout = tasty({
styles: {
display: 'grid',
gridColumns: {
'': '1sf 1sf 1sf',
'@tablet': '1sf 1sf',
'@mobile': '1sf',
},
gap: {
'': '4x',
'@mobile': '2x',
},
padding: {
'': '8x 4x',
'@mobile': '4x 2x',
},
},
});Sub‑Elements
Style inner elements from the parent. Typed sub‑components via the elements prop.
const Card = tasty({
styles: {
padding: '4x',
radius: '1cr',
border: true,
Title: {
$: '>',
preset: 'h3',
color: '#primary-accent-text',
},
Content: {
$: '>',
preset: 't2',
color: '#primary-text',
},
},
elements: { Title: 'h3', Content: 'div' },
});
// Usage:
// <Card>
// <Card.Title>Hello</Card.Title>
// <Card.Content>World</Card.Content>
// </Card>Configuration
Set up global states, custom units, functions, and reusable style recipes — all in one place.
import { configure } from '@tenphi/tasty';
configure({
states: {
'@dark': '@root(theme=dark) | @media(prefers-color-scheme: dark)',
'@mobile': '@media(w < 640px)',
},
units: {
col: (n) => `${(n / 12) * 100}%`,
gap: '4px',
},
funcs: {
fluid: ([min, max]) =>
`clamp(${min.output}, 2.5vw + 1rem, ${max.output})`,
},
recipes: {
card: {
padding: '3x',
fill: '#surface',
radius: '1cr',
border: true,
shadow: '0 1x 3x #shadow-sm',
},
},
});Complete Ecosystem
Tools that complete the picture
Glaze
OKHSL‑based color theme generator with WCAG contrast solving. Generate light, dark, and high‑contrast palettes from a single hue.
ColorsESLint Plugin
27 lint rules that validate style properties, value syntax, token existence, and enforce best practices.
LintingVS Code Extension
Syntax highlighting for Tasty styles in TypeScript and TSX. Highlights tokens, units, states, and presets.
DXStart building with Tasty
One install. Zero config. Ship beautiful, accessible UIs today.
$ pnpm add @tenphi/tasty