Skip to content

How to programmatically apply a Drupal recipe

The following script demonstrates how to programmatically apply a Drupal recipe using Drupal 10.3 or later.

The script supports two execution modes:

  1. Batch mode: Ideal for large or complex recipes.
  2. Immediate mode: For simple, lightweight recipe applications.

Requirements: Drupal 10.3 or later.

Here are some of the ways you can run the recipe batch process inside a Drupal module:

  • hook_install() / hook_update_N() - Immediate mode only
  • Event subscriber / cron / queue - Immediate mode only
  • Custom route + controller
  • Form submit handler
  • Drush command
  • Menu/toolbar link
  • Service/helper class
<?php

use Drupal\Core\Batch\BatchBuilder;
use Drupal\Core\Recipe\Recipe;
use Drupal\Core\Recipe\RecipeRunner;

// There are two ways to apply a recipe programmatically: immediately, or as a
// batch job.
// The batch job is generally the safer option, since more complex recipes could
// risk timing out if they try to do too much at once.

// So, first thing you need to do is get a Recipe object. Point it to the
// directory where recipe.yml is:
$recipe = Recipe::createFromDirectory('/path/of/some/recipe');

// Now, if you want to make that a batch job:

$batch = new BatchBuilder();
foreach (RecipeRunner::toBatchOperations($recipe) as $operation) {
  $batch->addOperation(...$operation);
}

// Maybe you do other stuff with $batch here, like adding more operations,
// setting up the messages, etc.

// Finally, to kick off the job:
batch_set($batch->toArray());

// And that's that.

// If you want to just immediately apply the recipe, without giving the user any
// feedback, that's even easier:

RecipeRunner::processRecipe($recipe);

// Done-zo.

// By the way, BOTH of these techniques will automatically apply all the recipes
// that $recipe depends upon. You don't have to worry about setting it up or
// recursing or any of that nonsense. The recipe system handles it for you.