On this page
- Drupal version compatibility
- Prerequisites
- 1. Downloading Drupal core
- Modern Drupal (10, 11, 8.8+)
- Legacy Drupal (7.x)
- Docker users
- 2. Initial setup & installation
- Web root configuration
- Installation methods
- 3. Managing modules and themes
- Discovery commands
- 4. Advanced configuration
- Customizing installation paths
- Managing third-party libraries (Asset Packagist)
- Step 1: Initialize the Project
- Step 2: Configure composer.json
- Step 3: Handle naming mismatches (optional)
- Step 4: Require libraries
- 5. Patching projects
- Patch levels for modern Drupal
- Re-applying patches
- 6. Maintenance & version control
- Requiring a specific commit
- Managing existing sites
- Git integration
- Standard .gitignore snippet
- Switching from core-recommended to core
- Appendix: semantic versioning shim
Using Composer to Install Drupal and Manage Dependencies
This documentation needs work. See "Help improve this page" in the sidebar.
Composer can be used to manage Drupal and all its dependencies, including modules, themes, and libraries.
Drupal version compatibility
- Modern: 11.x, 10.x
- Legacy: 9.x, 8.x, 7.x
Prerequisites
1. Downloading Drupal core
Modern Drupal (10, 11, 8.8+)
The recommended template is drupal/recommended-project. This ensures dependencies match the official release and places the web-accessible files in a /web folder.
- Standard installation:
composer create-project drupal/recommended-project my_site_name- This is the default starting point for all new projects.
- It creates a project in the
my_site_namedirectory and automatically executescomposer install.
- Specific version installation (e.g., 9.3.12):
composer create-project drupal/recommended-project:9.3.12 my_site_name- Use this to match a specific environment or test a previous release.
- All releases can be found at Releases for Drupal core.
- Development or pre-release installation (e.g., Drupal 11 alpha/beta):
composer create-project drupal/recommended-project:^11@alpha- Use this for testing upcoming features or the latest major branch.
- Setting
@alphaas minimum stability allows Composer to pull non-stable releases, such as beta or RC. Use@devfor the absolute latest development release.
- Modified installation: If you want to modify
composer.jsonproperties (like renaming the web root) before the initial download, use the--no-installflag.- Example:
composer create-project --no-install drupal/recommended-project my_site_name.
- Example:
- Non-standard path installation: If you require a directory structure without the
/websubdirectory or have advanced requirements, see Appendix: manual project initialization.
Note for Windows Users: If a command fails with a "Could not parse version" error, replace single quotes (') with double quotes (") or remove them entirely (e.g., drupal/recommended-project:^10).
For more information, see recommended-project on Github.
Legacy Drupal (7.x)
Use the community-maintained project template:
composer create-project drupal-composer/drupal-project:7.x-dev -n my_site_name
For more information, see Composer template for Drupal projects on Github.
Docker users
If Composer is not installed locally, run the command via a container:
docker run --rm -i --tty -v $PWD:/app composer create-project drupal/recommended-project my_site_name --ignore-platform-reqs
2. Initial setup & installation
Web root configuration
The my_site_name directory contains files that should be outside of your web root and not accessible by the web server, such as composer.json and the /vendor folder.
- DocumentRoot: The web root is the
my_site_name/webdirectory. Set your Apache or Nginx configuration to point there. - Alternate web root: If you need to rename
/webtopublic_html, modify the web-root (under drupal-scaffold) and installer-paths keys incomposer.json. See Customizing installation paths.
Installation methods
- Standard web interface: Navigate to your site's URL in a browser and follow the setup wizard. You will need database credentials and basic site information.
- Command line (Drush):
composer require drush/drushdrush site:install. Without arguments, it installs the standard profile and prompts for database credentials.
For more information, visit the site install document on the official Drush site.
-
Quick-start demo: To evaluate Drupal with the Umami demo:
php ./web/core/scripts/drupal quick-start demo_umami
3. Managing modules and themes
All commands must be executed at the root of your project, where the composer.json file is located, not inside the web or core directories. Using Composer for all modules and themes is critical; mixing manual updates with Composer can cause site failures.
- Download a module or theme: Composer automatically downloads the project and its required third-party libraries.
- Run:
composer require drupal/PROJECT_NAME - Example:
composer require drupal/token - You can use either the project name or a specific module name within a project (e.g.,
composer require drupal/features_extraorcomposer require drupal/fe_block).
- Run:
- Download a specific version: Use this when a module requires a specific version for compatibility.
- Run:
composer require 'drupal/PROJECT_NAME:VERSION' - Example:
composer require 'drupal/token:^1.5' - Note: On Windows, single quotes may cause "Could not parse version constraint" errors. Use double quotes
"drupal/token:^1.5"or no quotes.
- Run:
- Using development versions: Dev versions are git clones and do not include Drupal.org version metadata. This means the Drupal core Update Manager may not function properly for them unless you install the Composer Deploy project. Use dev versions only as a temporary measure.
To use the module, you must still enable it via the Drupal admin UI (/admin/modules) or using Drush: drush en module_name. For example: drush en drupal/token.
Note: For Drupal 7 versioning and legacy mapping, see the Appendix.
Discovery commands
Use these to find and inspect packages without leaving the terminal:
- Search:
composer search <keyword>(e.g.,composer search honey-pot). - Show versions:
composer show drupal/recommended-project --all(Checks available core updates) - Browse:
composer browse drupal/<keyword>(Opens the project page in your browser)
4. Advanced configuration
Customizing installation paths
To change where packages are downloaded (e.g., moving contributed code into /contrib or relocating the web root), modify the installer-paths section in composer.json. This uses the composer/installers package.
Example configuration:
"extra": {
"installer-paths": {
"web/core": ["type:drupal-core"],
"web/libraries/{$name}": ["type:drupal-library"],
"web/modules/contrib/{$name}": ["type:drupal-module"],
"web/themes/contrib/{$name}": ["type:drupal-theme"],
"web/modules/custom/{$name}": ["type:drupal-custom-module"]
}
}
Warning: The first matching entry in installer-paths is used.
Custom paths: Custom module/theme paths require composer/installers v1.0.24+.
Managing third-party libraries (Asset Packagist)
Use Asset Packagist to manage JavaScript and CSS libraries (e.g., Leaflet, Slick, or Chosen) via Composer.
Note: This method is intended for PHP-based applications like Drupal. For decoupled or pure front-end projects, use native tools like NPM or Yarn.
Step 1: Initialize the Project
Run the following command to allow Composer to install packages to custom directories (like /libraries):
composer require oomphinc/composer-installers-extender
Step 2: Configure composer.json
Add the Asset Packagist repository and define the installation paths in your composer.json file.
Step 2.1. Add the repository
"repositories": [
{
"type": "composer",
"url": "https://asset-packagist.org"
}
]
2.2. Define installer types and paths
Add or append npm-asset and bower-asset to the extra section. This ensures libraries land in Drupal's /libraries folder instead of /vendor
"extra": {
"installer-types": ["npm-asset", "bower-asset"],
"installer-paths": {
"web/libraries/{$name}": [
"type:drupal-library",
"type:npm-asset",
"type:bower-asset"
]
}
}
Step 3: Handle naming mismatches (optional)
If a package name (e.g., chosen-js) does not match the directory name a Drupal module expects (e.g., chosen), add a specific override above the general rule:
"installer-paths": {
"web/libraries/chosen": ["npm-asset/chosen-js"],
"web/libraries/{$name}": [
"type:drupal-library",
"type:npm-asset",
"type:bower-asset"
]
}
Step 4: Require libraries
You can now require libraries using the npm-asset or bower-asset prefixes:
# Install a specific version of Leaflet
composer require bower-asset/leaflet:1.0.3
# Install Chosen JS
composer require npm-asset/chosen-js:^1.8For more information, visit the official Asset Packagist site.
5. Patching projects
To apply community fixes automatically, use cweagans/composer-patches.
composer require cweagans/composer-patches:~2.0 --update-with-dependencies
Patch levels for modern Drupal
Because modern Drupal uses a /web subdirectory, you must specify the patch level in composer.json, or core patches will fail to apply. Without -p2, Composer will look in the wrong directory level.
"extra": {
"patchLevel": {
"drupal/core": "-p2",
"drupal/contrib_module": "-p1"
},
"patches": {
"drupal/core": {
"Fix for issue X": "patches/fix-issue.patch"
}
}
}Warning: Do not hotlink patches from Drupal.org. Download them and commit them to your local repository to prevent build failures if the remote file changes or is deleted.
Re-applying patches
If you add a patch to composer.json but do not change the version of the module, running composer install will not apply it. To force Composer to apply the new patch without updating the module version, use one of these methods:
- Modern method: Use
--lockto update the lock file metadata for a specific package:composer update drupal/core-recommended --lock - Universal/Legacy method: If the patch fails to trigger, delete the package folder and run install. This is the most reliable way to ensure a fresh, patched download.
rm -rf vendor/drupal/package_name composer install
6. Maintenance & version control
Requiring a specific commit
If you need a specific fix in a development branch that hasn't been tagged yet:
- Run:
composer require drupal/PROJECT_NAME:VERSION#COMMIT_HASH - Example:
composer require drupal/eck:1.x-dev#ecf376 - Warning: The Composer team does not actively support commit references.
composer validatewill issue a warning, and this should only be a temporary solution.
Managing existing sites
If your site was originally installed without Composer (via zip/tarball):
Use the Composerize Drupal plugin to automatically generate a composer.json based on your existing codebase.
Alternatively, manually add the Drupal.org repository to your existing composer.json.
Git integration
- Copy the example gitignore and adjust for the
/websubdirectory:cp web/example.gitignore .gitignore - Adjust paths from
sites/toweb/sites/using: sed -i'.bak' -z 's|\nsites|\nweb/sites|g' .gitignore - After running the sed command to adjust paths, ensure you remove the backup file created:
rm .gitignore.bak
Note:The .gitignore should be at the same level as the vendor directory.
Standard .gitignore snippet
Ensure your .gitignore includes these core entries to prevent committing generated code or sensitive credentials:
# Ignore directories managed by Composer
/vendor/
/web/core/
/web/modules/contrib/
/web/themes/contrib/
/web/profiles/contrib/
/web/libraries/
# Ignore configuration and user-generated content
/web/sites/*/settings.php
/web/sites/*/services.yml
/web/sites/*/files/
/web/sites/*/private/
Switching from core-recommended to core
If you need to update a specific dependency (like Guzzle) beyond what core-recommended allows, you can switch to the less restrictive drupal/core:
composer remove --no-update drupal/core-recommendedcomposer require --update-with-all-dependencies drupal/core
Warning: This may update Guzzle from version 6 to 7, which can cause fatal errors in some code. Dependencies will no longer be locked to specific minor versions, so take care during future updates.
Review the instructions for managing Guzzle updates without drupal/core-recommended.
Appendix: semantic versioning shim
Drupal.org translates legacy version formats into Semantic Versioning (SemVer) for Composer compatibility.
| Legacy Format | Translated Format | Example |
|---|---|---|
{Platform.x}-{major}.{minor} |
{major}.{minor}.0 |
7.x-3.4 → 3.4.0 |
{7.x-major.x-dev} |
{major}.x-dev |
7.x-1.x-dev → 1.x-dev |
{Platform.x}-{major}.{minor}-{stability#} |
{major}.{minor}.0-{stability}{#} |
7.x-3.4-beta2 → 3.4.0-beta2 |
Note: Unstable releases (e.g., 7.x-1.0-unstable3) are not translated and are unavailable to Composer.
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion