Le Blog technique d'Adimeo

dr : le nouveau CLI natif de Drupal, futur remplaçant de Drush

Rédigé par Pierre Waldura | Sep 21, 2026, 6:00:00 AM

Chaque nouvelle version de Drupal apporte son lot de nouveautés. Avec Drupal 11.4, c’est presque une petite révolution qui a été introduite puisque le cœur de Drupal propose désormais un nouveau CLI (Command Line Interface – outil en ligne de commande qui permet de réaliser des actions sur un logiciel/ordinateur/site) : dr, disponible via vendor/bin/dr.

Le but du Drupal Core CLI dr est ni plus ni moins d’intégrer progressivement les usages de Drush directement au cœur. Présent depuis 2013, Drush est LE CLI indissociable de tout développement Drupal pour pouvoir exécuter toutes sortes d’actions sur le site sans passer par l’interface utilisateur (vidage des caches, import/export de la configuration, mise à jour de la base de données…). La seule chose, c’est que Drush est un outil externe : il n’est donc pas obligatoire au bon fonctionnement de Drupal. Or, les usages montrent que Drush est quasiment tout le temps intégré à un nouveau développement. Alors pourquoi ne pas gagner du temps et l’intégrer directement à Drupal ?

Nous allons voir dans la suite de cet article quelles sont les nouveautés apportées par dr, les différences avec Drush et surtout comment faire pour rendre ses commandes Drush compatibles avec dr.

dr : quelles nouveautés ?

Commençons par lister les nouveautés apportées par ce nouveau CLI. Plusieurs évolutions importantes sont à noter :

  • dr est intégré au cœur de Drupal : contrairement à Drush qui est un projet externe, il n’est plus nécessaire de requérir la dépendance pour pouvoir utiliser les commandes.
  • Nouveau chemin d’entrée : l’exécutable utilise le chemin “ vendor/bin/dr ”.
  • Réduction de la dépendance des modules à Drush : tout module Drupal peut déclarer ses propres commandes Drush mais cela implique que le module dépende de Drush (i.e. si Drush n’est pas installé, le module ne peut pas être installé). Avec dr, le CLI devient extensible sans déclaration explicite de dépendance.
  • Découverte automatique des commandes : l’utilisation des attributs PHP (Symfony attributes) permet de détecter automatiquement les commandes dr sans passer par la déclaration d’un service Drupal.
  • Injection automatique des dépendances (autowiring) sans configuration supplémentaire.
  • Basé sur Symfony Console  Les commandes doivent notamment retourner des constantes Symfony Command (ex : Command::SUCCESS) ce qui améliore la compréhension.
  • Philosophie différente : une classe égale une commande, tandis qu’avec Drush une même classe peut contenir plusieurs commandes.

Différences entre dr et Drush

dr ne reposant pas sur les mêmes bases que Drush, quelques changements et améliorations sont apportés.

Comparaison technique

Le tableau suivant montre les différences techniques entre dr et Drush.

Aspect
dr (Drupal Core CLI)
Drush
Chemin de l’exécutable
vendor/bin/dr
vendor/bin/drush
Emplacement des fichiers de commandes dans un module
src/Command/
src/Drush/Commands/
Classe de base
Symfony\Component\Console\Command\Command ou classe invocable
Drush\Commands\DrushCommands
Déclaration des commandes
Attributs Symfony (#[AsCommand], #[Argument], #[Option], #[Ask])
Attributs et/ou annotations Drush (#[CLI\Command], #[CLI\Argument])
Enregistrement
Automatique (la classe est découverte automatiquement par le Compiler Pass de Drupal)
Déclaration explicite dans un fichier drush.services.yml (ou autowiring récent selon les versions)
Méthode d’exécution
Utilisation de la méthode execute(InputInterface $input, OutputInterface $output)
ou bien de la méthode __invoke(…)
Exécution de n’importe quelle méthode associée à l’attribut #[Command(name: 'macommande')]
ou bien l’annotation “ @command macommande ” utilisés pour déclarer la commande.

Les commandes utilisateur changent-elles ?

Pour l’instant, très peu.

L’objectif n’est pas de renommer toutes les commandes Drush mais de fournir progressivement un équivalent dans le cœur de Drupal. Aujourd’hui “ vendor/bin/dr ” devient simplement le nouveau point d’entrée officiel.

Les commandes Drush les plus connues (cr, cim, cex, updb, sql:*, etc.) restent aujourd’hui associées à Drush et ne disposent pas encore toutes d’un équivalent dans dr. La migration des fonctionnalités est prévue pour être progressive.

Drush disparaît-il ?

A court et moyen terme, non. Le nouveau Drupal Core CLI est encore considéré comme expérimental.

Drupal présente dr comme le successeur à long terme, mais Drush continue d’être maintenu et reste pleinement compatible avec Drupal 11. Les deux outils vont coexister durant une période de transition. Les commandes Drush existantes continuent donc de fonctionner et les modules peuvent même proposer des commandes compatibles avec les deux CLI pendant cette phase.

Transformer ses commandes Drush en commandes dr

À ce stade, l’envie peut être grande de transformer ses commandes Drush en commandes dr pour pouvoir anticiper au maximum la transition et ne pas être pris au dépourvu. Pourtant, la meilleure approche consiste à conserver ses commandes Drush et à ajouter la compatibilité avec dr.

La meilleure approche : la compatibilité avec les deux CLI

Comme Drush et dr attendent des métadonnées différentes et ont un flux d’exécution légèrement différent, la communauté encourage pour le moment les développeurs qui souhaitent utiliser le nouveau CLI à rendre leurs commandes compatibles avec dr tout en conservant la compatibilité avec Drush.

Pour ce faire, il est conseillé d’utiliser le système de déclaration de services de Drupal :

  • Un fichier est déclaré comme service standard de Drupal et contient toute la logique du code.
  • Deux autres fichiers (l’un pour Drush, l’autre pour dr) ne contenant que la déclaration de la commande sont utilisés pour appeler cette logique.

Pourquoi cette approche est la plus sûre ?

  • De cette manière, la logique du code est positionnée dans une classe indépendante du CLI qui va l’utiliser. Cela évite la duplication inutile de code.
  • Meilleure maintenabilité - Si demain Drush ou dr font évoluer leur système d’implémentation de commande, il n’y aura qu’à mettre à jour le fichier d’appel sans toucher à la logique du code.
  • Utilisation distincte des outils de formatage - En séparant les fichiers d’appel, vous vous garantissez de pouvoir utiliser au maximum les outils de formatage de Drush wrapper ou bien de Symfony via le Core wrapper dans le retour de votre commande.

Exemple d’implémentation d’une commande compatible avec Drush et le Drupal Core CLI dr

Voyons maintenant par l’exemple comment mettre en place une commande qui soit compatible avec Drush et avec dr et respecte le pattern défini juste au-dessus.

Étape 1 : Création du service contenant la logique du code

  • Création du fichier my_module/src/MyModuleLogic.php
  • Ce fichier contient par exemple le code suivant :
namespace Drupal\my_module;
class MyModuleLogic {
  public function sayHello(string $name): string {
   return "Hello, $name!";
  }
}
  • Déclaration du service dans le fichier my_module/my_module.services.yml
services:
  my_module.my_module_logic:
    class: Drupal\my_module\MyModuleLogic

Étape 2 : Création du fichier d’appel dr

  • Création du fichier my_module/src/Command/HelloCommand.php
  • Ce fichier contient le code suivant pour pouvoir appeler la méthode sayHello() du fichier MyModuleLogic.php :
namespace Drupal\my_module\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Attribute\Argument;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Command\Command;
use Drupal\my_module\MyModuleLogic;

#[AsCommand(name: 'my_module:hello', description: 'Says hello.')]
class HelloCommand {
 public function __construct(private readonly MyModuleLogic $logic) {}

 public function __invoke(OutputInterface $output, #[Argument] string $name): int {
  // L’appel à la logique du code est fait via cette unique ligne.
  $result = $this->logic->sayHello($name);
  $output->writeln($result);
  return Command::SUCCESS;
 }
}

Étape 3 : Création du fichier d’appel Drush

  • Création du fichier my_module/src/Drush/Commands/HelloDrushCommand.php
  • Ce fichier contient le code suivant pour pouvoir appeler la méthode sayHello() du fichier MyModuleLogic.php :
namespace Drupal\my_module\Drush\Commands;

use Drush\Attributes as CLI;
use Drush\Commands\DrushCommands;
use Drupal\my_module\MyModuleLogic;

class HelloDrushCommands extends DrushCommands {
 public function __construct(private readonly MyModuleLogic $logic) {
  parent::__construct();
 }

 #[CLI\Command(name: 'my_module:hello', aliases: ['mm-hello'])]
 #[CLI\Argument(name:'name', description: 'The name to greet')]
 public function sayHello(string $name) {
  // L’appel à la logique du code est fait via cette unique ligne.
  $result = $this->logic->sayHello($name);
  $this->logger()->success($result);
  }
}
  • Déclaration de la commande Drush dans le fichier my_module/drush.services.yml avec déclaration de la dépendance au service “ my_module_logic ”.
services:
 my_module.commands:
  class: Drupal\my_module\Drush\Commands\HelloDrushCommands
  arguments:
   - '@my_module.my_module_logic'
  tags:
   - { name: drush.command }

Désormais, nous pouvons utiliser conjointement :

  • vendor/bin/dr my_module:hello friend
  • vendor/bin/drush my_module:hello --name=friend

Pour renvoyer le résultat “ Hello friend ” dans l’invité de commande.

Si demain, par exemple, la déclaration d’une commande Drush devait évoluer, nous n’aurions alors qu’à modifier le fichier d’appel HelloDrushCommands.php sans que cela n’impacte ni la logique du code ni le fichier d’appel dr.


Pour résumer, l’introduction du CLI natif dr marque le début d’une transition où une partie des usages de Drush sera progressivement intégrée au cœur de Drupal. Le projet est porté en collaboration avec plusieurs mainteneurs de Drush afin d’assurer une migration progressive plutôt qu’une rupture.

Drush n’est donc pas abandonné pour le moment, il reste pleinement compatible avec Drupal 11 et est pour le moment l’outil le plus complet en comparaison avec dr. Néanmoins, il n’y a aucun doute quant au fait que dr va s’étoffer au fil des nouvelles versions de Drupal et prendre progressivement la place de Drush.

La phase transitoire est donc à mettre à profit par les développeurs pour commencer à appréhender ce nouveau CLI et mettre à jour leurs commandes Drush pour les rendre compatibles avec le Drupal Core CLI dr.


Pour en savoir plus : Drush command porting guide to the new dr Drupal core CLI

Crédit photo : BalanceFormcreative