Custom Drush command for managing Twig debugging and CSS/JS aggregation

Last updated on
25 April 2025

This page has not yet been reviewed by Development tools maintainer(s) and added to the menu.

The theme:dev Drush command was added in Drush 13.6, see Toggle Twig debugging and CSS/JS aggregation with Drush. Users with a PHP version below 8.3 can use this method, see Drush compatibility.

The custom Drush command theme:dev makes it easy to switch between development and production settings on your Drupal site. With a single command, you can toggle CSS/JS aggregation and Twig debugging — two settings that are often adjusted while debugging.

  • on mode turns off aggregation and enables Twig debugging, which is perfect while you're actively developing or theming your site.
  • off mode turns on aggregation (for better performance) and turns off Twig debugging. Use this when you're preparing for production.

Steps to add custom theme:dev Drush command:

  1. Create a drush directory in the Drupal project root, add a Commands sub-directory inside, and finally a ThemeDevCommands.php file for this structure:
    drupal
    ├── composer.json
    ├── composer.lock
    ├── drush
    │   └── Commands
    │       └── ThemeDevCommands.php
    ├── vendor
    └── web
    
  2. Add this inside ThemeDevCommands.php:
     
    <?php
    
    declare(strict_types=1);
    
    namespace Drush\Commands;
    
    use Drush\Attributes as CLI;
    use Drush\Commands\DrushCommands;
    use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
    use Drupal\Core\Config\ConfigFactoryInterface;
    use Symfony\Component\DependencyInjection\ContainerInterface;
    
    final class ThemeDevCommands extends DrushCommands
    {
        const DEV = 'theme:dev';
    
        public function __construct(
            protected KeyValueFactoryInterface $keyValueFactory,
            protected ConfigFactoryInterface $configFactory
        ) {
        }
    
        public static function create(ContainerInterface $container): self
        {
            return new self(
                $container->get('keyvalue'),
                $container->get('config.factory')
            );
        }
    
        /**
         * Toggle Twig development and cache aggregation settings.
         *
         * When enabled:
         * - Disables render cache, dynamic page cache, and page cache.
         * - Enables Twig debug mode (e.g., `dump()` function, template suggestions).
         * - Disables Twig cache (templates always recompiled).
         * - Disables CSS and JS aggregation.
         *
         * When disabled, restores default performance-oriented settings.
         *
         * Clears all Drupal caches to apply changes immediately.
         */
        #[CLI\Command(name: self::DEV, aliases: ['thdev'])]
        #[CLI\Argument(name: 'mode', description: '"on" or "off"', suggestedValues: ['on', 'off'])]
        #[CLI\Usage(name: 'drush theme:dev on', description: 'Disables CSS/JS aggregation and enables Twig debug settings.')]
        #[CLI\Usage(name: 'drush theme:dev off', description: 'Enables CSS/JS aggregation and disables Twig debug settings.')]
        public function toggleDevMode(string $mode): void
        {
            if (!in_array($mode, ['on', 'off'])) {
                throw new \InvalidArgumentException("Invalid mode. Use 'on' or 'off'.");
            }
    
            $devMode = $mode === 'on';
    
            $this->keyValueFactory->get('development_settings')->setMultiple([
                'disable_rendered_output_cache_bins' => $devMode,
                'twig_debug' => $devMode,
                'twig_cache_disable' => $devMode,
            ]);
    
            $this->configFactory->getEditable('system.performance')
                ->set('css.preprocess', !$devMode)
                ->set('js.preprocess', !$devMode)
                ->save();
    
            drupal_flush_all_caches();
    
            $this->logger()->success(sprintf(
                'Developer mode %s: CSS/JS aggregation %s, Twig debug settings %s.',
                $mode === 'on' ? 'enabled' : 'disabled',
                $devMode ? 'disabled' : 'enabled',
                $devMode ? 'enabled' : 'disabled'
            ));
        }
    }
    

Disable aggregation and enable Twig debugging:

drush theme:dev on

Enable aggregation and disable Twig debugging:

drush theme:dev off

There's even an alias:

drush thdev on
drush thdev off

Built by @keshav patel, see #3342678: Easy way to bypass caching and aggregation with Drush or settings.php and Add Drush command to toggle Twig debugging and CSS/JS aggregation #6267.

Help improve this page

Page status: No known problems

You can: