--- title: Recipes parent: packages --- # Recipes Create multi-variant styles with a type-safe runtime API, heavily inspired by [Stitches](https://stitches.dev). As with the rest of vanilla-extract, all styles are generated at build time. > 💡 Recipes is an optional package built on top of vanilla-extract using its [function serialization API.](/documentation/api/add-function-serializer) It doesn't have privileged access to vanilla-extract internals so you're also free to build alternative implementations. ## Setup ```bash npm install @vanilla-extract/recipes ``` ## recipe Creates a multi-variant style function that can be used at runtime or statically in `.css.ts` files. Accepts an optional set of `base` styles, `variants`, `compoundVariants` and `defaultVariants`. ```ts compiled // button.css.ts import { recipe } from '@vanilla-extract/recipes'; export const button = recipe({ base: { borderRadius: 6 }, variants: { color: { neutral: { background: 'whitesmoke' }, brand: { background: 'blueviolet' }, accent: { background: 'slateblue' } }, size: { small: { padding: 12 }, medium: { padding: 16 }, large: { padding: 24 } }, rounded: { true: { borderRadius: 999 } } }, // Applied when multiple variants are set at once compoundVariants: [ { variants: { color: 'neutral', size: 'large' }, style: { background: 'ghostwhite' } } ], defaultVariants: { color: 'accent', size: 'medium' } }); ``` With this recipe configured, you can now use it in your templates. ```ts // app.ts import { button } from './button.css.ts'; document.write(` `); ``` Your recipe configuration can also make use of existing variables, classes and styles. For example, you can pass in the result of your [`sprinkles`](/documentation/packages/sprinkles) function directly. ```ts // button.css.ts import { recipe } from '@vanilla-extract/recipes'; import { reset } from './reset.css.ts'; import { sprinkles } from './sprinkles.css.ts'; export const button = recipe({ base: [reset, sprinkles({ borderRadius: 'round' })], variants: { color: { neutral: sprinkles({ background: 'neutral' }), brand: sprinkles({ background: 'brand' }), accent: sprinkles({ background: 'accent' }) }, size: { small: sprinkles({ padding: 'small' }), medium: sprinkles({ padding: 'medium' }), large: sprinkles({ padding: 'large' }) } }, defaultVariants: { color: 'accent', size: 'medium' } }); ``` The recipes function also exposes an array property `variants` that includes all the variants from your recipe. ```ts button.variants(); // -> ['color', 'size'] ``` ## Recipe class name selection Recipes function exposes internal class names in `classNames` property. The property has two predefined props: `base` and `variants`. The `base` prop includes base class name. It is always defined even if you do not have any base styles. The `variants` prop includes class names for each defined variant. ```ts // app.css.ts console.log(button.classNames.base); // -> app_button__129pj250 console.log(button.classNames.variants.color.neutral); // -> app_button_color_neutral__129pj251 console.log(button.classNames.variants.size.small); // -> app_button_size_small__129pj254 ``` ## RecipeVariants A utility to make use of the recipe’s type interface. This can be useful when typing functions or component props that need to accept recipe values as part of their interface. ```ts // button.css.ts import { recipe, RecipeVariants } from '@vanilla-extract/recipes'; export const button = recipe({ variants: { color: { neutral: { background: 'whitesmoke' }, brand: { background: 'blueviolet' }, accent: { background: 'slateblue' } }, size: { small: { padding: 12 }, medium: { padding: 16 }, large: { padding: 24 } } } }); // Get the type export type ButtonVariants = RecipeVariants; // the above will result in a type equivalent to: export type ButtonVariants = { color?: 'neutral' | 'brand' | 'accent'; size?: 'small' | 'medium' | 'large'; }; ```