npx skills add commercetools/nimbus --skill writing-recipesWriting Recipes Skill
You are a Nimbus recipe specialist. This skill helps you create, update, or validate Chakra UI v3 recipes using Nimbus design tokens.
Critical Requirement
Nimbus uses Chakra UI v3 mechanics with Nimbus design tokens. You MUST NOT use default Chakra tokens.
Mode Detection
Parse the request to determine the operation:
- create - Generate new recipe files and registration
- update - Modify existing recipe (add variants, change styles)
- validate - Check recipe compliance with guidelines
If no mode is specified, default to create.
Required Research (All Modes)
Before implementation, you MUST research in parallel:
- Read recipe guidelines and decision flow:
cat docs/file-type-guidelines/recipes.md - Read naming conventions:
cat docs/naming-conventions.md - Analyze similar recipes:
ls packages/nimbus/src/components/*/*.recipe.ts cat packages/nimbus/src/components/button/button.recipe.ts # Standard cat packages/nimbus/src/components/menu/menu.recipe.ts # Slot - Query Chakra UI v3 docs via context7 for recipe mechanics:
Library: @chakra-ui/react Query: "defineRecipe defineSlotRecipe patterns" - Review available Nimbus tokens:
cat packages/tokens/src/index.ts
Create Mode
Recipe Type Decision
You MUST determine if the component needs:
- Standard Recipe (
defineRecipe) - Single-element components- Examples: Button, Badge, Tag, Link
- File:
{component}.recipe.ts
- Slot Recipe (
defineSlotRecipe) - Multi-part components- Examples: Input, Card, Menu, Dialog
- Files:
{component}.recipe.ts+{component}.slots.tsx
File Structure
You MUST create files in this structure:
packages/nimbus/src/components/{component}/
├── recipes/
│ └── {component}.recipe.ts # REQUIRED
├── {component}.types.ts # MUST update with recipe types
└── {component}.slots.tsx # REQUIRED for slot recipes
Standard Recipe Template
import { defineRecipe } from '@chakra-ui/react'
/**
* Recipe for the {ComponentName} component.
*
* @see {@link https://nimbus.docs.link/{component}}
*/
export const {componentName}Recipe = defineRecipe({
className: '{component-name}',
description: 'Recipe for {ComponentName} component',
base: {
// Base styles - MUST use Nimbus tokens
},
variants: {
size: {
sm: { /* SHOULD define */ },
md: { /* MUST define as default */ },
lg: { /* SHOULD define */ },
},
appearance: {
// MUST define at least one appearance
},
},
defaultVariants: {
// MUST specify defaults for all variants
size: 'md',
},
})
Slot Recipe Template
import { defineSlotRecipe } from '@chakra-ui/react'
/**
* Recipe for the {ComponentName} component slots.
*
* @see {@link https://nimbus.docs.link/{component}}
*/
export const {componentName}Recipe = defineSlotRecipe({
className: '{component-name}',
description: 'Recipe for {ComponentName} component',
slots: ['root', /* slot names */],
base: {
root: { /* base styles */ },
// MUST define base for each slot
},
variants: {
size: {
md: {
root: { /* MUST define for each slot */ },
},
},
},
defaultVariants: {
size: 'md',
},
})
Type Integration
You MUST update the component's types file:
import { type RecipeVariantProps } from '@chakra-ui/react'
import { type {componentName}Recipe } from './recipes/{component}.recipe'
/**
* Recipe variant props for {ComponentName}.
*/
export type {ComponentName}RecipeProps = RecipeVariantProps<typeof {componentName}Recipe>
/**
* Props for the {ComponentName} component.
*/
export type {ComponentName}Props = {ComponentName}RecipeProps & {
// Component-specific props
}
Slots File (Slot Recipes Only)
You MUST create a slots file for slot recipes:
import { createSlotRecipeContext } from '@chakra-ui/react'
import { {componentName}Recipe } from './recipes/{component}.recipe'
const { withProvider, withContext } = createSlotRecipeContext({
recipe: {componentName}Recipe,
})
export const {ComponentName}SlotProvider = withProvider(/* implementation */)
export const use{ComponentName}Styles = withContext
Registration (CRITICAL)
You MUST register the recipe in packages/nimbus/src/theme/recipes.ts:
For standard recipes:
export { {componentName}Recipe } from '../components/{component}/recipes/{component}.recipe'
// Add to recipes object:
recipes: {
'{component-name}': {componentName}Recipe,
}
For slot recipes:
export { {componentName}Recipe } from '../components/{component}/recipes/{component}.recipe'
// Add to slotRecipes object:
slotRecipes: {
'{component-name}': {componentName}Recipe,
}
Verification
You MUST run these commands after creation:
pnpm --filter @commercetools/nimbus typecheck
pnpm --filter @commercetools/nimbus build-theme-typings
pnpm --filter @commercetools/nimbus build
You MUST verify generated types exist:
ls packages/nimbus/styled-system/recipes/{component-name}.*
Update Mode
Process
- You MUST read the current recipe file
- You MUST analyze similar patterns in other recipes
- You SHOULD preserve existing variant structure
- You MUST maintain token consistency
- You MUST update JSDoc if adding new capabilities
Common Updates
- Add variant - New size, appearance, or state
- Add compound variant - Combination of existing variants
- Modify base styles - Change default styling
- Add slots - Convert standard to slot recipe (requires major refactor)
Post-Update
You MUST verify the changes:
pnpm --filter @commercetools/nimbus typecheck
pnpm --filter @commercetools/nimbus build
Validate Mode
Validation Checklist
You MUST validate against these requirements:
File Structure
- Recipe file location MUST be:
packages/nimbus/src/components/{component}/recipes/{component}.recipe.ts - Import MUST be from
@chakra-ui/react - Export name MUST follow pattern:
{componentName}Recipe
Recipe Definition
- MUST use
defineRecipe()ordefineSlotRecipe() - MUST have
classNameproperty (kebab-case) - MUST have
descriptionproperty - MUST have JSDoc comment with link
Token Usage (CRITICAL)
- MUST use Nimbus tokens, NOT Chakra defaults
- MUST NOT have hardcoded values:
blue.500,#fff,16px - MUST use token references:
colors.*,spacing.*,radii.*
Variants
- MUST have
defaultVariantsdefined - Variant names SHOULD follow conventions (lowercase)
- Size variant SHOULD include:
sm,md,lg - Default size MUST be
md - MUST use
:first-of-type/:last-of-typeinstead of:first-child/:last-child(ensures SSR hydration consistency)
Registration (CRITICAL)
- Recipe MUST be exported from
packages/nimbus/src/theme/recipes.ts - Recipe MUST be in theme's
recipesorslotRecipesobject - Generated types MUST exist in
styled-system/recipes/
Type Integration
-
RecipeVariantPropstype MUST be defined - Component props MUST extend recipe props
Validation Report Format
## Recipe Validation: {ComponentName}
### Status: [✅ PASS | ❌ FAIL | ⚠️ WARNING]
### Files Reviewed
- Recipe file
- Types file
- Slots file (if applicable)
- Theme registration
### ✅ Compliant
[List passing checks]
### ❌ Violations (MUST FIX)
- [Violation with guideline reference]
### ⚠️ Warnings (SHOULD FIX)
- [Non-critical improvements]
### Registration
- Recipe Type: [Standard | Slot]
- Registered: [YES | NO]
- Types Generated: [YES | NO]
Critical Requirements
You MUST follow design token requirements from
docs/file-type-guidelines/recipes.md. This includes:
- Using Nimbus tokens (NOT Chakra defaults like blue.500 or white)
- Proper token categories (colors.primary.base, spacing.4, etc.)
- NO hardcoded values
See docs/naming-conventions.md for recipe naming patterns.
Error Recovery
If verification fails:
- You MUST check recipe syntax (commas, brackets)
- You MUST verify theme export exists
- You MUST ensure tokens are valid
- You SHOULD check for circular dependencies
- You MAY need to rebuild theme typings
Reference Examples
You SHOULD reference these recipes:
- Standard:
packages/nimbus/src/components/button/recipes/button.recipe.ts - Slot:
packages/nimbus/src/components/input/recipes/input.recipe.ts - Complex:
packages/nimbus/src/components/badge/recipes/badge.recipe.ts
RFC 2119 Key Words
- MUST / REQUIRED / SHALL - Absolute requirement
- MUST NOT / SHALL NOT - Absolute prohibition
- SHOULD / RECOMMENDED - Should do unless valid reason not to
- SHOULD NOT / NOT RECOMMENDED - Should not do unless valid reason
- MAY / OPTIONAL - Truly optional
Execute recipe operation for: $ARGUMENTS