← All recipes

Delete Inactive Themes

Removes all inactive themes keeping only the latest default WordPress theme.

echo "🔎 Finding the latest default WordPress theme to preserve..."
latest_default_theme=$(cat <<'PHP_SCRIPT' | wp eval-file -
<?php
$response = wp_remote_get(
  'https://api.wordpress.org/themes/info/1.2/?action=query_themes&request[author]=wordpressdotorg&request[per_page]=100'
);
if (is_wp_error($response)) {
  exit(1);
}
$data = json_decode(wp_remote_retrieve_body($response));
if (is_null($data) || isset($data->themes) === false) {
  exit(1);
}
$twentyThemes = [];
foreach ($data->themes as $theme) {
  if (isset($theme->slug) && str_starts_with($theme->slug, 'twenty')) {
    $twentyThemes[] = $theme->slug;
  }
}
if (empty($twentyThemes)) {
  exit(1);
}
echo $twentyThemes[0];
PHP_SCRIPT
)

if [ $? -ne 0 ] || [ -z "$latest_default_theme" ]; then
  echo "❌ Error: Could not determine the latest default theme. Aborting." >&2
  exit 1
fi
echo "✅ The latest default theme is '$latest_default_theme'. This will be preserved."

mapfile -t inactive_themes < <(wp theme list --status=inactive --field=name)
if [ ${#inactive_themes[@]} -eq 0 ]; then
  echo "👍 No inactive themes found to process. All done!"
  exit 0
fi

echo "🚀 Processing ${#inactive_themes[@]} inactive themes..."
for theme in "${inactive_themes[@]}"; do
  # Check if the current inactive theme is the one we want to keep
  if [[ "$theme" == "$latest_default_theme" ]]; then
    echo "⚪️ Keeping inactive default theme: $theme"
  else
    echo "❌ Deleting inactive theme: $theme"
    wp theme delete "$theme"
  fi
done

echo "✨ Cleanup complete."
Run it across a fleet

Open the console in CaptainCore Manager, pick the target sites, choose this recipe from the Cookbook picker and press run. The CLI streams each site's output back to the dock.

About the console →