Skip to content

createRecipes

createRecipes returns cx, cva, and sva that combine their classes with a join function of your choice, or whose recipes do not cache their class names. Call it once, in a module of your own, and import the functions from there:

src/lib/recipe.ts
import { createRecipes } from "@lynstack/class-recipe";
import { twMerge } from "tailwind-merge";
export const { cx, cva, sva } = createRecipes({ join: twMerge });
Option Description
join Optional. Combines the class strings of a selection into its class name, such as twMerge from tailwind-merge or cn. Defaults to cx.
cache Optional. Whether recipes cache the class names of each declared selection. Defaults to true.
Function Description
cx Joins class names like the default cx, then passes the result to join, unless it is empty.
cva Creates recipes with the join and cache options.
sva Creates slot recipes with the join and cache options.
createRecipe The same function as cva.
createSlotRecipe The same function as sva.

Without options, it returns the functions the package exports.

A join function receives the class strings in order of precedence, lowest first, and returns the class name: any (...classNames: readonly string[]) => string works. It always receives at least one class string, and never an empty one. A recipe calls it once for each declared selection and caches the result, then again for each call that passes className or classNames, or an undeclared option (see How it works).

Pass cache: false to build the class names on every call instead, alone or together with join:

export const { cx, cva, sva } = createRecipes({ cache: false });

Without the cache, a slot recipe returns a new object on every call, even for the same variants. Keep the cache unless you have measured that a recipe is called with so many different selections, each only once, that storing them costs more than building them.

To turn the cache off for one recipe only, pass cache: false in its config instead (see cva). The cache of a recipe’s config overrides the option of createRecipes, so a recipe whose config sets cache: true caches its class names even when the option turns the cache off.

A recipe’s cache keeps every class name it builds for as long as the recipe exists, up to one for each combination of declared options. On a server, a recipe whose variants come from requests lets clients choose those combinations, and a recipe that declares many of them grows its cache with each new one. Pass cache: false in the config of such a recipe, and keep the cache for the others:

const badge = cva({
cache: false,
base: "rounded-full px-2 text-xs",
variants: { tone: { neutral: "bg-gray-100", danger: "bg-red-100" } },
});

A recipe with few combinations, or whose variants the program chooses itself, needs no change (see Caching).