React implementation of Stitches CSS-in-JS library with type-safe styling and variants
—
Set up Stitches with custom themes, media queries, utilities, and type mappings. The createStitches function allows you to create a fully customized styling system tailored to your design requirements.
Creates a configured Stitches instance with custom settings.
/**
* Creates a configured Stitches instance
* @param config - Configuration object with theme, media, utilities, and mappings
* @returns Stitches instance with styled, css, globalCss, keyframes, createTheme functions
*/
function createStitches<Config extends StitchesConfig>(
config?: Config
): StitchesInstance<Config>;
interface StitchesConfig {
/** CSS class prefix for generated classes */
prefix?: string;
/** Media query breakpoints */
media?: { [name: string]: string };
/** Design tokens organized by scale */
theme?: ThemeObject;
/** Mapping of CSS properties to theme scales */
themeMap?: { [property: string]: keyof ThemeObject };
/** Custom utility functions */
utils?: { [name: string]: (value: any) => StyleObject };
}
interface StitchesInstance<Config> {
/** Create styled React components */
styled: StyledFunction<Config>;
/** Create CSS classes */
css: CssFunction<Config>;
/** Apply global styles */
globalCss: GlobalCssFunction<Config>;
/** Create keyframe animations */
keyframes: KeyframesFunction<Config>;
/** Create theme variants */
createTheme: CreateThemeFunction<Config>;
/** Configuration object */
config: Config;
/** CSS class prefix */
prefix: string;
/** Default theme object */
theme: ThemeInstance<Config>;
/** Reset all styles */
reset(): void;
/** Get generated CSS text */
getCssText(): string;
/** String representation of CSS */
toString(): string;
}Usage Examples:
import { createStitches } from "@stitches/react";
// Basic configuration
const { styled, css, globalCss, theme, createTheme } = createStitches({
theme: {
colors: {
primary: 'blue',
secondary: 'gray'
},
space: {
sm: '8px',
md: '16px',
lg: '24px'
}
}
});
// Use configured instance
const Button = styled('button', {
backgroundColor: '$colors$primary',
padding: '$space$md'
});Define design tokens organized by semantic scales.
interface ThemeObject {
/** Color tokens for backgrounds, text, borders */
colors?: { [token: string]: string };
/** Spacing tokens for margins, padding, gaps */
space?: { [token: string]: string };
/** Font size tokens */
fontSizes?: { [token: string]: string };
/** Font family tokens */
fonts?: { [token: string]: string };
/** Font weight tokens */
fontWeights?: { [token: string]: string | number };
/** Line height tokens */
lineHeights?: { [token: string]: string | number };
/** Letter spacing tokens */
letterSpacings?: { [token: string]: string };
/** Size tokens for width, height */
sizes?: { [token: string]: string };
/** Border width tokens */
borderWidths?: { [token: string]: string };
/** Border style tokens */
borderStyles?: { [token: string]: string };
/** Border radius tokens */
radii?: { [token: string]: string };
/** Box shadow tokens */
shadows?: { [token: string]: string };
/** Z-index tokens */
zIndices?: { [token: string]: number };
/** Transition tokens */
transitions?: { [token: string]: string };
}Usage Examples:
const { styled } = createStitches({
theme: {
colors: {
// Semantic colors
primary: '#0066cc',
secondary: '#6b7280',
success: '#059669',
warning: '#d97706',
danger: '#dc2626',
// Neutral scale
gray50: '#f9fafb',
gray100: '#f3f4f6',
gray200: '#e5e7eb',
gray500: '#6b7280',
gray900: '#111827',
// Brand colors
brand: '#8b5cf6',
accent: '#06b6d4'
},
space: {
px: '1px',
0: '0',
1: '0.25rem', // 4px
2: '0.5rem', // 8px
3: '0.75rem', // 12px
4: '1rem', // 16px
5: '1.25rem', // 20px
6: '1.5rem', // 24px
8: '2rem', // 32px
10: '2.5rem', // 40px
12: '3rem', // 48px
16: '4rem', // 64px
20: '5rem', // 80px
24: '6rem' // 96px
},
fontSizes: {
xs: '0.75rem', // 12px
sm: '0.875rem', // 14px
base: '1rem', // 16px
lg: '1.125rem', // 18px
xl: '1.25rem', // 20px
'2xl': '1.5rem', // 24px
'3xl': '1.875rem', // 30px
'4xl': '2.25rem' // 36px
},
fonts: {
sans: 'ui-sans-serif, system-ui, sans-serif',
serif: 'ui-serif, Georgia, serif',
mono: 'ui-monospace, "Cascadia Code", monospace'
}
}
});Define responsive breakpoints for consistent media queries.
interface MediaConfig {
[breakpointName: string]: string;
}Usage Examples:
const { styled, css } = createStitches({
media: {
sm: '(min-width: 640px)',
md: '(min-width: 768px)',
lg: '(min-width: 1024px)',
xl: '(min-width: 1280px)',
'2xl': '(min-width: 1536px)',
// Custom breakpoints
mobile: '(max-width: 767px)',
tablet: '(min-width: 768px) and (max-width: 1023px)',
desktop: '(min-width: 1024px)',
// Feature queries
hover: '(hover: hover)',
dark: '(prefers-color-scheme: dark)',
motion: '(prefers-reduced-motion: no-preference)'
},
theme: {
colors: {
primary: 'blue',
text: 'black'
}
}
});
// Use configured breakpoints
const ResponsiveBox = styled('div', {
padding: '16px',
fontSize: '16px',
'@sm': {
padding: '20px',
fontSize: '18px'
},
'@lg': {
padding: '24px',
fontSize: '20px'
},
'@hover': {
'&:hover': {
backgroundColor: '$colors$primary'
}
},
'@dark': {
backgroundColor: 'black',
color: 'white'
}
});Map CSS properties to theme scales for automatic token resolution.
interface ThemeMapConfig {
[cssProperty: string]: keyof ThemeObject;
}Usage Examples:
const { styled } = createStitches({
theme: {
colors: {
primary: 'blue',
secondary: 'gray'
},
space: {
sm: '8px',
md: '16px',
lg: '24px'
},
custom: {
borderRadius: '4px',
transition: '0.2s ease'
}
},
themeMap: {
// Default mappings (included automatically)
color: 'colors',
backgroundColor: 'colors',
borderColor: 'colors',
margin: 'space',
padding: 'space',
// Custom mappings
borderRadius: 'custom',
transition: 'custom',
boxShadow: 'shadows',
// Map multiple properties to same scale
width: 'sizes',
height: 'sizes',
minWidth: 'sizes',
maxWidth: 'sizes'
}
});
// Properties automatically resolve to theme tokens
const ThemedBox = styled('div', {
// These use themeMap to resolve tokens
backgroundColor: '$primary', // $colors$primary
padding: '$lg', // $space$lg
borderRadius: '$borderRadius', // $custom$borderRadius
transition: '$transition' // $custom$transition
});
// Without themeMap, you'd need full token paths
const VerboseBox = styled('div', {
backgroundColor: '$colors$primary',
padding: '$space$lg',
borderRadius: '$custom$borderRadius'
});Create custom CSS utility functions for common patterns.
interface UtilsConfig {
[utilityName: string]: (value: any) => StyleObject;
}Usage Examples:
const { styled } = createStitches({
theme: {
space: {
1: '4px',
2: '8px',
3: '12px',
4: '16px'
},
colors: {
primary: 'blue',
secondary: 'gray'
}
},
utils: {
// Margin utilities
m: (value) => ({
margin: value
}),
mx: (value) => ({
marginLeft: value,
marginRight: value
}),
my: (value) => ({
marginTop: value,
marginBottom: value
}),
mt: (value) => ({ marginTop: value }),
mr: (value) => ({ marginRight: value }),
mb: (value) => ({ marginBottom: value }),
ml: (value) => ({ marginLeft: value }),
// Padding utilities
p: (value) => ({
padding: value
}),
px: (value) => ({
paddingLeft: value,
paddingRight: value
}),
py: (value) => ({
paddingTop: value,
paddingBottom: value
}),
// Size utilities
size: (value) => ({
width: value,
height: value
}),
// Flex utilities
center: () => ({
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}),
// Border utilities
borderX: (value) => ({
borderLeft: value,
borderRight: value
}),
borderY: (value) => ({
borderTop: value,
borderBottom: value
}),
// Gradient utilities
linearGradient: (value) => ({
backgroundImage: `linear-gradient(${value})`
}),
// Truncate text
truncate: () => ({
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
})
}
});
// Use utility functions in components
const UtilityBox = styled('div', {
// Use custom utilities with theme tokens
p: '$4', // padding: $space$4
mx: '$2', // marginLeft: $space$2, marginRight: $space$2
size: '100px', // width: 100px, height: 100px
center: true, // display: flex, alignItems: center, justifyContent: center
linearGradient: '45deg, $colors$primary, $colors$secondary',
truncate: true,
// Combine with regular CSS
backgroundColor: '$colors$primary',
borderRadius: '8px'
});Add prefixes to generated CSS classes for namespace isolation.
Usage Examples:
const { styled, css } = createStitches({
prefix: 'my-app',
theme: {
colors: {
primary: 'blue'
}
}
});
const Button = styled('button', {
backgroundColor: '$colors$primary'
});
// Generated class names will be prefixed
console.log(Button.className); // "my-app-c-abc123"
const cardStyles = css({
padding: '16px'
});
console.log(cardStyles.className); // "my-app-c-def456"Create multiple Stitches instances for different contexts or component libraries.
Usage Examples:
// Main app instance
const mainStitches = createStitches({
prefix: 'app',
theme: {
colors: {
primary: 'blue',
secondary: 'gray'
}
}
});
// Component library instance
const libStitches = createStitches({
prefix: 'ui-lib',
theme: {
colors: {
brand: 'purple',
neutral: 'silver'
}
}
});
// Use different instances
const AppButton = mainStitches.styled('button', {
backgroundColor: '$colors$primary'
});
const LibButton = libStitches.styled('button', {
backgroundColor: '$colors$brand'
});
// Classes won't conflict due to prefixes
// AppButton.className: "app-c-abc123"
// LibButton.className: "ui-lib-c-def456"Configure Stitches for server-side rendering scenarios.
Usage Examples:
// Server-side setup
const { styled, getCssText, reset } = createStitches({
theme: {
colors: { primary: 'blue' }
}
});
// On server - render page
function renderPage() {
// Reset styles for clean slate
reset();
// Render app (generates styles)
const html = renderToString(<App />);
// Get generated CSS
const cssText = getCssText();
return `
<html>
<head>
<style id="stitches">${cssText}</style>
</head>
<body>
<div id="root">${html}</div>
</body>
</html>
`;
}
// Client-side hydration
function hydrate() {
// Hydrate will work correctly with server-rendered styles
ReactDOM.hydrate(<App />, document.getElementById('root'));
}// Configured Stitches instance with full type safety
type ConfiguredStitches<Config extends StitchesConfig> = {
styled: StyledFunction<Config>;
css: CssFunction<Config>;
globalCss: GlobalCssFunction<Config>;
keyframes: KeyframesFunction<Config>;
createTheme: CreateThemeFunction<Config>;
theme: ThemeInstance<Config>;
config: Config;
getCssText(): string;
reset(): void;
};
// Type-safe theme token access
type ThemeTokens<Theme> = {
[Scale in keyof Theme]: {
[Token in keyof Theme[Scale]]: string;
};
};
// Type-safe utility function parameters
type UtilityFunction<Config> = (value: any) => CSS<
Config['media'],
Config['theme'],
Config['themeMap'],
Config['utils']
>;Usage Examples:
// Fully typed configuration
const { styled } = createStitches({
theme: {
colors: {
primary: 'blue',
secondary: 'gray'
} as const,
space: {
sm: '8px',
md: '16px'
} as const
},
utils: {
px: (value: string) => ({
paddingLeft: value,
paddingRight: value
})
}
});
// TypeScript ensures token and utility existence
const TypedButton = styled('button', {
backgroundColor: '$colors$primary', // ✓ Valid
// backgroundColor: '$colors$invalid', // ✗ TypeScript error
px: '$space$md', // ✓ Valid utility with valid token
// px: '$space$invalid', // ✗ TypeScript error
});Install with Tessl CLI
npx tessl i tessl/npm-stitches--react