CLI API Overview

Last updated on
23 June 2026

This documentation needs work. See "Help improve this page" in the sidebar.

The Command-Line Interface (CLI) API inherits from the Symfony Console Component for the Symfony release included in Drupal. As of Drupal 11.4.0, modules may provide commands, which can make using and developing Drupal web sites more efficient or allow systems to automate routine tasks in Drupal. However it is important to remember that not all users are comfortable with the CLI, and it is not a replacement for user interfaces.

Creating a basic command

Your command is discoverable by using the AsCommand class attribute and placing the command within the Drupal\my_module\Command namespace (src/Command directory). The Symfony Console Commands documentation page is a useful reference for authoring commands.

Symfony 8.1 or greater

The AsCommand attribute will apply to functions as well as classes, which will allow multiple commands to be defined in a class. However Drupal 11 has not yet adopted Symfony 8.1.

declare(strict_types=1);

namespace Drupal\my_module\Command;

use Drupal\Core\StringTranslation\StringTranslationTrait;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;


/**
 * A basic example command.
 */
#[AsCommand(
  name: 'my-module:greet',
  description: 'Displays a greeting.',
)]
class GreetCommand {

  use StringTranslationTrait;

  /**
   * {@inheritdoc}
   */
  public function __invoke(InputInterface $input, OutputInterface $output): int {

    // Using SymfonyStyle will allow colors for errors, successes,
    // sections, and other fancy things.
    $io = new SymfonyStyle($input, $output);
    $io->info((string) $this->t('Hello, World'));

    // Always use the respective class constant for the return type
    // such as SUCCESS, FAILURE, or INVALID for consistency.
    return Command::SUCCESS;
  }

}

Rebuild the cache, and the command should be listed as my-module:greet and executed by running ./vendor/bin/dr my-module:greet. The output should be:

To be determined (TBD)

Providing input (arguments or options) to a command

In the above example, we passed in $input, but the method arguments for invoke can be described by the Argument and Option argument attributes. This is now the preferred method for describing a command, but this can still be done by using the configure method.

A command option is provided like --option value while a command argument is provided as simply the value.

  public function __invoke(#[Argument] $name, OutputInterface $output): int {

    // Using SymfonyStyle will allow colors for errors, successes,
    // sections, and other fancy things.
    $io = new SymfonyStyle($input, $output);
    $io->info((string) $this->t('Hello, @name', ['@name' => $name));

    // Always use the respective class constant for the return type
    // such as SUCCESS, FAILURE, or INVALID for consistency.
    return Command::SUCCESS;
  }

Using a Drupal service in a command

TBD

Creating a command that requires Drupal to be installed

TBD

Help improve this page

Page status: Needs work

You can: