Essential tools: Composer, Drush, and the core CLI
Three command-line tools cover almost everything you do with a Drupal site outside the browser: Composer manages the code, Drush operates the site, and core’s own CLI handles bootstrap-level jobs. This page gives you the working set of commands for each and the rule for choosing between them.
You know which tool owns which job, you can run the 10 or so commands that make up daily Drupal work, and you understand what vendor/bin/dr adds in Drupal 11.4. This page is a tour, not a reference: each tool’s own documentation covers the full command surface.
Prerequisites
Section titled “Prerequisites”- A working environment and installed site, per Set up your environment and Install Drupal core.
- All commands below run from the project root. They are shown in DDEV form (
ddev composer ...,ddev drush ...), which runs them inside the container against the container’s PHP and database. Not using DDEV? Use the Personalize control in the top bar to switch every command on the site to its native form.
Manage code with Composer
Section titled “Manage code with Composer”Composer answers one question: what code is in this project? It never touches your database or your site’s configuration.
# Add a contrib (community-contributed) module. Code only; it is not enabled yet.ddev composer require drupal/pathauto
# Update Drupal core within the allowed version range.ddev composer update "drupal/core-*" --with-all-dependencies
# Rebuild vendor/ and web/core exactly as composer.lock describes.ddev composer installThe drupal/ package namespace resolves against packages.drupal.org, which the drupal/recommended-project template preconfigures. Two habits matter:
- Commit
composer.lockalways. It is the difference between “works on my machine” and a reproducible build. - Downloading a module is not installing it. After
composer require, the code sits inweb/modules/contrib/doing nothing until you enable it, which is a site operation and therefore Drush’s job.
Operate the site with Drush
Section titled “Operate the site with Drush”Drush talks to an installed site: it bootstraps Drupal (runs core’s startup sequence that loads the database connection, services, and configuration), loads your services, and acts on the database and configuration. These are the commands you will run many times a day:
ddev drush cache:rebuild # cr - rebuild all caches and the containerddev drush user:login # uli - print a one-time admin login URLddev drush pm:install pathauto # in - enable a module (and its dependencies)ddev drush config:export # cex - write active config to the sync directoryddev drush config:import # cim - apply the sync directory to the siteddev drush updatedb # updb - run pending update hooksddev drush status # bootstrap, versions, paths at a glancedrush cache:rebuild is the one you will type most. Drupal caches discovered routes, services, plugins, and templates aggressively; after adding any of those, a rebuild is what makes Drupal notice. Debug a Drupal site covers when you need it and when you do not.
The config pair (cex/cim) is the backbone of team workflows: everything you build in the admin UI is configuration that exports to YAML, gets reviewed like code, and imports on deploy. The configuration management workflow page owns that story.
Drush also generates code (drush generate module, drush generate controller), runs SQL (drush sql:cli), executes one-off PHP against the booted site (drush php:eval), and manages users. When these docs say “the CLI” without qualification, they mean Drush.
Know the core CLI: dr Added in 11.4
Section titled “Know the core CLI: dr ”Drupal core ships its own command-line application: vendor/bin/dr, a standard Symfony Console app wired up by Drupal\Core\Command\DrupalApplication. Drush is a separate project you add with Composer; dr is part of core itself, exposed through core’s composer.json bin entry. On Drupal 11.3 and earlier, php web/core/scripts/drupal ... runs a fixed set of commands (quick-start, install, server, generate-theme, and the recipe commands); from 11.4 that script is a deprecated shim for dr, which adds cache:rebuild and the module-provided command discovery described below (see the change record).
Five commands are registered before Drupal boots, which means they work even with no installed site or a completely broken one:
vendor/bin/dr quick-start # install + serve a throwaway site (SQLite)vendor/bin/dr install # install Drupal from a profile or recipevendor/bin/dr server # serve an installed site with PHP's web servervendor/bin/dr cache:rebuild # rebuild caches without a full bootstrapvendor/bin/dr generate-theme # create a theme by copying a starterkitFor anything else, dr bootstraps the site and discovers commands provided by installed modules: a class in a module’s src/Command/ directory with the #[AsCommand] attribute is registered automatically, with constructor dependencies injected from the service container. The CLI commands topic documents both the discovery and the command-authoring patterns, and a --url option selects the site when one codebase serves several.
Choose the right tool
Section titled “Choose the right tool”| Job | Tool |
|---|---|
| Add, update, or remove code | Composer |
| Enable modules, manage config, users, caches, deploys | Drush |
| Install or serve a site with zero setup, fix a site too broken to bootstrap, scaffold a theme | dr (or core/scripts/drupal before 11.4) |
| Run a command a specific module provides | Whichever the module targets; module-provided commands increasingly ship for dr |
Why does Drush still matter when core has a CLI? Coverage. Core’s built-in commands are deliberately minimal bootstrap-level tools, while Drush carries the operational surface teams deploy with: config:import, updatedb, deploy, site aliases for running commands against remote environments, code generators, and SQL tooling. Treat dr as core’s foundation, already worth knowing for quick-starts and broken-site recovery, and Drush as the day-to-day workhorse these docs assume.
Verify
Section titled “Verify”ddev drush statusprints the Drupal and Drush versions andDrupal bootstrap : Successful.ddev composer validatereportscomposer.jsonis valid.- On Drupal 11.4 or later,
ddev exec vendor/bin/dr listshows the built-in commands plus any provided by installed modules. On 11.3,ddev exec php web/core/scripts/drupal listshows the bootstrap-level commands.
Variations
Section titled “Variations”- Without DDEV: switch commands to native form with the Personalize control in the top bar. Composer then runs with your host PHP; Drush and
drare atvendor/bin/drushandvendor/bin/dr. - In CI and deployment: the same three tools, no browser:
composer install --no-dev --optimize-autoloader, thendrush deploy(which runsupdatedb,config:import, cache rebuilds, and deploy hooks in order). The deployment workflow page covers ordering and rollback. - Writing your own commands: module-provided console commands are a how-to of their own; until then, the
CLI commands topicshows both the attribute-based and the service-tag registration styles.
Related
Section titled “Related”- Debug a Drupal site applies these tools to the “why is my change not showing?” loop.
- Configuration management workflow builds the team workflow on
cex/cim. - Anatomy of a Drupal project explains the directories Composer writes to.
- Verify agent-generated Drupal code: these same tools, plus PHPStan and PHPCS, are the gates an AI coding agent must pass.
- Drush documentation is the full command reference.
Was this page helpful?
Drupal is a registered trademark of Dries Buytaert.