React implementation of Stitches CSS-in-JS library with type-safe styling and variants
—
Create and manage design tokens with type-safe theme references and dynamic theme switching. The theme system provides a structured approach to managing colors, spacing, typography, and other design tokens across your application.
Creates theme objects for design token management with optional naming.
/**
* Creates a theme object with design tokens
* @param theme - Object containing design token scales
* @returns Theme object with className, selector, and token properties
*/
function createTheme(theme: ThemeObject): string & ThemeTokens & ThemeMetadata;
/**
* Creates a named theme object with design tokens
* @param name - Theme name for CSS class generation
* @param theme - Object containing design token scales
* @returns Named theme object with className, selector, and token properties
*/
function createTheme(name: string, theme: ThemeObject): string & ThemeTokens & ThemeMetadata;
interface ThemeObject {
colors?: { [token: string]: string };
space?: { [token: string]: string };
fontSizes?: { [token: string]: string };
fonts?: { [token: string]: string };
fontWeights?: { [token: string]: string | number };
lineHeights?: { [token: string]: string | number };
letterSpacings?: { [token: string]: string };
sizes?: { [token: string]: string };
borderWidths?: { [token: string]: string };
borderStyles?: { [token: string]: string };
radii?: { [token: string]: string };
shadows?: { [token: string]: string };
zIndices?: { [token: string]: number };
transitions?: { [token: string]: string };
}
interface ThemeMetadata {
/** CSS class name for applying this theme */
className: string;
/** CSS selector for targeting this theme */
selector: string;
}Usage Examples:
import { createTheme } from "@stitches/react";
// Create default theme
const lightTheme = createTheme({
colors: {
primary: 'blue',
secondary: 'gray',
background: 'white',
text: 'black',
success: 'green',
warning: 'orange',
danger: 'red'
},
space: {
1: '4px',
2: '8px',
3: '12px',
4: '16px',
5: '24px',
6: '32px'
},
fontSizes: {
xs: '12px',
sm: '14px',
md: '16px',
lg: '18px',
xl: '20px',
'2xl': '24px'
},
fonts: {
sans: 'system-ui, sans-serif',
mono: 'Monaco, monospace'
}
});
// Create named theme variant
const darkTheme = createTheme('dark', {
colors: {
primary: 'lightblue',
secondary: 'lightgray',
background: '#1a1a1a',
text: 'white',
success: 'lightgreen',
warning: 'yellow',
danger: 'lightcoral'
}
});
// Apply theme to document or container
document.body.className = darkTheme;
// or
<div className={darkTheme}>
<App />
</div>Access theme tokens with type-safe references and auto-completion.
interface ThemeTokens {
[scale: string]: {
[token: string]: ThemeToken;
};
}
interface ThemeToken {
/** The token value */
value: string;
/** CSS custom property name */
variable: string;
/** Scale name this token belongs to */
scale: string;
/** Token name within the scale */
token: string;
}Usage Examples:
const theme = createTheme({
colors: {
primary: 'blue',
secondary: 'gray'
},
space: {
sm: '8px',
md: '16px',
lg: '24px'
}
});
// Access theme tokens
console.log(theme.colors.primary.value); // 'blue'
console.log(theme.colors.primary.variable); // '--colors-primary'
console.log(theme.space.md.value); // '16px'
// Use tokens in styles with $ prefix
const Button = styled('button', {
backgroundColor: '$colors$primary',
padding: '$space$md',
color: '$colors$secondary'
});
// Or use in CSS function
const cardStyles = css({
backgroundColor: '$colors$background',
padding: '$space$lg',
borderRadius: '$radii$md'
});Map CSS properties to theme scales for automatic token resolution.
interface DefaultThemeMap {
// Spacing properties
gap: 'space';
margin: 'space';
padding: 'space';
top: 'space';
right: 'space';
bottom: 'space';
left: 'space';
// Color properties
color: 'colors';
backgroundColor: 'colors';
borderColor: 'colors';
// Typography properties
fontSize: 'fontSizes';
fontFamily: 'fonts';
fontWeight: 'fontWeights';
lineHeight: 'lineHeights';
letterSpacing: 'letterSpacings';
// Size properties
width: 'sizes';
height: 'sizes';
minWidth: 'sizes';
maxWidth: 'sizes';
// Border properties
borderWidth: 'borderWidths';
borderRadius: 'radii';
// Shadow and effects
boxShadow: 'shadows';
zIndex: 'zIndices';
transition: 'transitions';
}
const defaultThemeMap: DefaultThemeMap;Usage Examples:
// Theme map allows shorthand token references
const Button = styled('button', {
// These automatically map to theme scales via defaultThemeMap
fontSize: '$md', // Maps to $fontSizes$md
padding: '$lg', // Maps to $space$lg
backgroundColor: '$primary', // Maps to $colors$primary
borderRadius: '$sm' // Maps to $radii$sm
});
// Custom theme map configuration
const { styled } = createStitches({
themeMap: {
...defaultThemeMap,
// Custom mappings
opacity: 'opacity',
transform: 'transforms'
},
theme: {
opacity: {
low: '0.5',
high: '0.9'
},
transforms: {
scale: 'scale(1.1)',
rotate: 'rotate(45deg)'
}
}
});Switch between themes dynamically at runtime.
Usage Examples:
import { useState } from 'react';
const lightTheme = createTheme({
colors: {
background: 'white',
text: 'black',
primary: 'blue'
}
});
const darkTheme = createTheme('dark', {
colors: {
background: '#1a1a1a',
text: 'white',
primary: 'lightblue'
}
});
function ThemeProvider({ children }) {
const [isDark, setIsDark] = useState(false);
const currentTheme = isDark ? darkTheme : lightTheme;
return (
<div className={currentTheme}>
<button onClick={() => setIsDark(!isDark)}>
Switch to {isDark ? 'Light' : 'Dark'} Theme
</button>
{children}
</div>
);
}Extend existing themes with additional or overridden tokens.
Usage Examples:
const baseTheme = createTheme({
colors: {
primary: 'blue',
secondary: 'gray',
background: 'white'
},
space: {
sm: '8px',
md: '16px',
lg: '24px'
}
});
// Extend with additional tokens
const extendedTheme = createTheme('extended', {
colors: {
...baseTheme.colors,
tertiary: 'green', // Add new color
primary: 'darkblue' // Override existing color
},
space: {
...baseTheme.space,
xl: '32px', // Add new spacing
xxl: '48px'
},
// Add completely new scale
fontSizes: {
sm: '14px',
md: '16px',
lg: '18px'
}
});Themes generate CSS custom properties for external integration.
Usage Examples:
const theme = createTheme({
colors: {
primary: 'blue',
secondary: 'gray'
},
space: {
md: '16px',
lg: '24px'
}
});
// CSS custom properties are automatically generated:
// --colors-primary: blue;
// --colors-secondary: gray;
// --space-md: 16px;
// --space-lg: 24px;
// Use in regular CSS
const regularCSS = `
.my-component {
background-color: var(--colors-primary);
padding: var(--space-lg);
}
`;
// Or in CSS-in-JS
const Component = styled('div', {
backgroundColor: 'var(--colors-primary)',
padding: 'var(--space-lg)'
});Handle theme application during server-side rendering.
Usage Examples:
// On the server
import { getCssText } from "@stitches/react";
const theme = createTheme({
colors: { primary: 'blue' }
});
// Apply theme class to HTML
const html = `
<html>
<head>
<style>${getCssText()}</style>
</head>
<body class="${theme}">
<div id="root">${renderToString(<App />)}</div>
</body>
</html>
`;
// On the client - hydration will work correctly
ReactDOM.hydrate(<App />, document.getElementById('root'));// Theme token type with scale and token information
interface ThemeToken<Token, Value, Scale, Prefix> {
/** Token name prefixed for CSS custom property */
readonly [Symbol.toPrimitive]: () => string;
/** Scale this token belongs to */
scale: Scale;
/** Token name within the scale */
token: Token;
/** Token value */
value: Value;
/** CSS custom property variable name */
variable: string;
}
// Type-safe theme value references
type ScaleValue<Scale, Config = null> =
Config extends null
? { readonly [K in $$ScaleValue]: Scale }
: Scale extends keyof Config['theme']
? `$${string & keyof Config['theme'][Scale]}`
: never;
// Property value with theme support
type PropertyValue<Property extends keyof CSSProperties, Config = null> =
Config extends null
? { readonly [K in $$PropertyValue]: Property }
: CSS<Config['media'], Config['theme'], Config['themeMap'], Config['utils']>[Property];Usage Examples:
// Type-safe theme token access
const theme = createTheme({
colors: {
primary: 'blue',
secondary: 'gray'
}
});
// TypeScript ensures token exists
const Button = styled('button', {
backgroundColor: '$colors$primary', // ✓ Valid
// backgroundColor: '$colors$invalid', // ✗ TypeScript error
});
// Extract theme type for other uses
type MyTheme = typeof theme;
type ColorTokens = keyof MyTheme['colors']; // 'primary' | 'secondary'Install with Tessl CLI
npx tessl i tessl/npm-stitches--react