Skip to content

Recipe System Overview

When to Use

Use Drupal Recipes (core since 10.3.0, May 2024) when you need shareable, tested configuration patterns that can be applied to any Drupal site. Use distributions for full site builds, config split for environment-specific config.

Decision

Situation Choose Why
Full site with opinionated defaults from scratch Distribution Replaces entire installation profile, controls all config
Reusable configuration patterns to apply to existing sites Recipe Composable, shareable, can be applied post-install
Environment-specific config Config Split Manages config variations across environments
Historical install profile replacement Recipe + custom code Install profiles are deprecated, recipes are the modern replacement

Pattern

The five pillars of recipes: extensions, config, config actions, default content, and config checkpoints (rollback on failure).

name: 'Content editor role'
description: 'Provides the Content editor role.'
type: 'User role'
install:
  - node
config:
  strict: false
  actions:
    user.role.content_editor:
      grantPermissions:
        - 'access administration pages'

RecipeRunner processes recipes in order: dependent recipes → install extensions → import config → apply config actions → import default content → trigger RecipeAppliedEvent. Config Checkpoint API creates snapshots before each step; on failure, config rolls back to pre-recipe state.

Recipes are ephemeral — once applied, the results become the site's responsibility. There is no "unapply" or managed state. The recipe itself is not tracked after application.

Common Mistakes

  • Wrong: Using install profiles for shareable functionality → Right: Install profiles are deprecated, use recipes
  • Wrong: Hardcoding site-specific values → Right: Use the input system for environment-specific values
  • Wrong: Treating recipes as migrations → Right: Recipes bootstrap sites, migrations transfer data
  • Wrong: Applying recipes multiple times expecting updates → Right: Recipes are apply-once; config is permanent after application
  • Wrong: Ignoring strict mode implications → Right: Strict mode validates existing config matches recipe expectations
  • Wrong: Expecting recipes to contain custom code → Right: Recipes are declarative YAML only; use modules for custom logic
  • Wrong: Expecting dynamic behavior → Right: No conditionals, loops, or runtime logic; static configuration only
  • Wrong: Expecting upgrade paths → Right: Recipes have no update mechanism; version changes require manual migration

See Also

  • Recipe YAML Schema
  • Reference: core/lib/Drupal/Core/Recipe/RecipeRunner.php
  • Reference: https://www.drupal.org/docs/extending-drupal/drupal-recipes