Composer
Composer is the dependency manager for PHP, and
Drupal projects use it for everything from core to contributed modules. You
declare the packages your project needs in composer.json, and Composer
resolves compatible versions, installs them, and records the exact result in
composer.lock.
This page is for developers who manage the packages of a project built from
Vortex. It shows you how to require, update, patch, and audit packages,
and it ends with a key-by-key reference of the shipped composer.json
file.
Installing
Add a package with composer require. Composer adds it to composer.json,
resolves its dependencies, and installs the package along with them. To add
the Devel module, for example, run the following command:
- Ahoy
- Docker Compose
ahoy composer require drupal/devel
docker compose exec cli composer require drupal/devel
By default, Composer installs only stable releases. To install a pre-release
of a package, such as an alpha, beta, or RC, add a stability flag to
its version constraint:
- Ahoy
- Docker Compose
ahoy composer require drupal/devel:^1.0.0@beta
docker compose exec cli composer require drupal/devel:^1.0.0@beta
The flag applies to that package alone. When the pre-release needs unstable
versions of its own dependencies, require each of them with a flag too, or
lower minimum-stability in composer.json. A stability level allows
itself and everything more stable, so beta allows beta, RC, and stable
releases, but not alpha or dev:
{
"minimum-stability": "beta"
}
Keep prefer-stable set to true, as Vortex ships it, so Composer
still picks a stable release wherever one satisfies the constraint.
Adding JavaScript/CSS libraries (npm packages)
To install a JavaScript or CSS library as a Drupal library with Composer,
define it as an inline Composer
package with the
drupal-library type. The installer-paths entry for that type puts it in
web/libraries/, where Drupal looks for libraries.
Don't use Asset Packagist to install front-end libraries. Drupal.org distributes its Composer packages under established security policies, while Asset Packagist is a third-party service without the safeguards that protect against supply chain attacks. Define the packages inline instead, as the following steps show.
To add the jQuery Easing library, for example, follow these steps:
-
Define the package in
composer.jsonunder therepositoriessection:{"repositories": [{"type": "package","package": {"name": "gdsmith/jquery.easing","type": "drupal-library","version": "1.4.1","source": {"type": "git","url": "https://github.com/gdsmith/jquery.easing","reference": "1.4.1"}}}]} -
Require the package using Composer:
- Ahoy
- Docker Compose
ahoy composer require gdsmith/jquery.easing
docker compose exec cli composer require gdsmith/jquery.easing
Confirm that the library's files are in web/libraries/jquery.easing/.
Updating
To update all dependencies, run the following command:
- Ahoy
- Docker Compose
ahoy composer update
docker compose exec cli composer update
If your project patches its dependencies, an update can fail
when a patch no longer applies to the new version of a dependency. Composer
then stops with No available patcher was able to apply patch, followed by
the patch URL and the package name.
A common fix is to remove the patches temporarily, run the update, and then reapply the patches one by one.
To update a specific package and its dependencies, run the following command:
- Ahoy
- Docker Compose
ahoy composer update vendor/package-name --with-dependencies
docker compose exec cli composer update vendor/package-name \
--with-dependencies
To update Drupal core, run the following command:
- Ahoy
- Docker Compose
ahoy composer update "drupal/core-*" --with-dependencies
docker compose exec cli composer update "drupal/core-*" \
--with-dependencies
Review the result with git diff and commit it as a single commit. Look
closely at the scaffold files that core updates, such as web/index.php and
web/sites/default/default.settings.php. Vortex ships its own
web/.htaccess and keeps it out of scaffolding, so a core update never
overwrites it. When a core release changes .htaccess, port the change by
hand.
Dependency bumping
Dependency bumping raises the
version constraints in composer.json to the versions you have installed.
That keeps a new dependency from dragging an installed package back to an
older version, and it gives Composer fewer versions to consider, which
speeds up dependency resolution.
Vortex turns this on with the bump-after-update setting, so every
composer update raises your constraints to the versions it installed.
Vortex bumps automatically because it's built for application projects (Drupal sites), where you control the whole dependency tree.
Bumping doesn't suit libraries (reusable packages). A library should keep
its constraints as broad as possible to spare downstream users dependency
hell. If you're building
a library, set bump-after-update: "dev" to bump only the development
dependencies, or turn automatic bumping off and run
composer bump --dev-only yourself.
Manual bumping
The following commands bump the constraints by hand:
# Bump all dependencies
composer bump
# Bump specific package
composer bump drupal/core-recommended
# Bump only development dependencies
composer bump --dev-only
# Preview changes without modifying files
composer bump --dry-run
Run them in the cli container, or prefix them with ahoy, as in
ahoy composer bump.
Overriding paths
To install a package somewhere other than the default location for its
type, add an entry to installer-paths in composer.json:
{
"extra": {
"installer-paths": {
"web/libraries/jquery-easing": [
"gdsmith/jquery.easing"
],
"web/libraries/{$name}": [
"type:drupal-library"
]
}
}
}
The first entry sends 1 package to a custom directory. The second is the
catch-all that routes every other drupal-library package to
web/libraries/{$name}. Composer uses the first entry that matches, so a
package-specific path must come before the catch-all for its type.
Vortex tooling package
Vortex ships its operational scripts, such as the database,
provisioning, deployment, and notification scripts, as the
drevops/vortex-tooling
Composer package. The scripts live in vendor/drevops/vortex-tooling/src/,
and Composer exposes each entry-point script as a binary under
vendor/bin/vortex-*, such as vendor/bin/vortex-provision or
vendor/bin/vortex-fetch-db.
See Architecture > Automation scripts for how the scripts are structured and how the router scripts dispatch to the provider-specific logic.
composer.json requires the package with a tilde constraint:
{
"require": {
"drevops/vortex-tooling": "~1.5.0"
}
}
The ~ constraint accepts patch releases but holds the minor version, so
composer update never moves you to a new minor release on its own. That
takes a change to the constraint in composer.json.
To update the package within the constraint, run the following command:
- Ahoy
- Docker Compose
ahoy composer update drevops/vortex-tooling
docker compose exec cli composer update drevops/vortex-tooling
To move to a new minor release, raise the constraint in composer.json
first and then run the update.
Don't edit files under vendor/drevops/vortex-tooling/src/. Git ignores
vendor/, so your changes never reach the repository, and Composer replaces
the files whenever it reinstalls or updates the package. Customize the
scripts through their environment variables or add your
own scripts under scripts/ (for example,
custom provision scripts). When
neither is enough, apply a patch, which Composer applies again
whenever it installs or updates the package.
Patching
Vortex patches Composer dependencies with
cweagans/composer-patches
2.x. Version 2.x applies patches with git apply, so they behave the same
on every platform. For the official documentation, see Composer Patches
Recommended
Workflows.
Understanding patches.lock.json
Composer Patches 2.x generates a patches.lock.json file. For each patch,
the file records the following:
- The package it applies to, its description, and its URL
- A SHA-256 checksum of the patch file
- The depth used to apply it
Commit this file to version control, like composer.lock. It makes builds
reproducible across your team and in CI/CD: the patch state stays explicit
and trackable, and the checksums in the file verify each patch's integrity.
Adding a new patch
To add a patch, follow these steps:
-
Define the patch in
composer.jsonunderextra.patches:"extra": {"patches": {"drupal/foobar": {"Fix for issue #123": "https://www.drupal.org/files/issues/fix-123.patch"}}} -
Regenerate
patches.lock.json:
- Ahoy
- Docker Compose
ahoy composer patches-relock
docker compose exec cli composer patches-relock
The output ends with patches.lock.json has been recreated successfully.
composer patches-repatch uninstalls every patched package from wherever
it's installed, such as web/modules/contrib/ or vendor/, and then runs
composer install to put it back. Any local edits in those packages are
lost.
- Remove and reinstall patched packages:
- Ahoy
- Docker Compose
ahoy composer patches-repatch
docker compose exec cli composer patches-repatch
- Update
composer.lock:
- Ahoy
- Docker Compose
ahoy composer update --lock
docker compose exec cli composer update --lock
Confirm that the patches-repatch output in step 3 has a
- Patching drupal/foobar line for the patched package.
Removing a patch
To remove a patch, follow these steps:
-
Delete the patch definition from
composer.json. -
Regenerate
patches.lock.json:
- Ahoy
- Docker Compose
ahoy composer patches-relock
docker compose exec cli composer patches-relock
- Delete the package's directory by hand, because
patches-repatchonly reinstalls packages that still have patches:
- Ahoy
- Docker Compose
ahoy cli rm -rf web/modules/contrib/foobar
docker compose exec cli rm -rf web/modules/contrib/foobar
- Reinstall without the patch:
- Ahoy
- Docker Compose
ahoy composer patches-repatch
docker compose exec cli composer patches-repatch
- Update
composer.lock:
- Ahoy
- Docker Compose
ahoy composer update --lock
docker compose exec cli composer update --lock
Confirm that patches.lock.json no longer lists the package, unless it
still has other patches.
Security auditing
composer audit checks the installed packages against published security
advisories and reports abandoned packages. Vortex configures Composer's
config.policy so that advisories never block composer install,
composer update, or composer require. composer audit itself still
fails when it finds an advisory, so vulnerabilities stay visible locally
and in CI.
➡️ See Dependency audit for the full policy reference, the audit commands, and ignoring assessed advisories.
composer.json reference
File overview
Vortex ships a pre-configured composer.json with the packages a Drupal
project needs and the development tools that check your code quality.
The composer.json file is Composer's core configuration file: it declares
your project's dependencies, where they install, and how Composer behaves.
The lint job in continuous integration checks it with
composer validate --strict and composer normalize --dry-run, so run
ahoy composer normalize after you edit it by hand.
This section describes each part of the file and its role.
Expand to see composer.json
{
"name": "your_org/your_site",
"description": "Drupal 11 implementation of YOURSITE for YOURORG",
"license": "proprietary",
"type": "project",
"require": {
"php": ">=8.4",
"composer/installers": "^2.3",
"cweagans/composer-patches": "^2.0",
"drevops/vortex-tooling": "~1.5.0",
"drupal/clamav": "^2.1",
"drupal/coffee": "^2.0.1",
"drupal/config_split": "^2.0.2",
"drupal/config_update": "^2@alpha",
"drupal/core-composer-scaffold": "~11.4.11",
"drupal/core-recommended": "~11.4.11",
"drupal/devel": "^5.5",
"drupal/drupal_helpers": "^2.2.0",
"drupal/environment_indicator": "^4.0.25",
"drupal/fast_404": "^3.7",
"drupal/generated_content": "^2.2.0",
"drupal/migrate_plus": "^6.0.10",
"drupal/migrate_tools": "^6.1.4",
"drupal/navigation_extra_tools": "^1.3.2",
"drupal/pathauto": "^1.15.0",
"drupal/redirect": "^1.13.0",
"drupal/redis": "^1.11",
"drupal/reroute_email": "^2.3@RC",
"drupal/robotstxt": "^1.6",
"drupal/sdc_devel": "^1.0.3",
"drupal/search_api": "^1.42.0",
"drupal/search_api_solr": "^4.4.0",
"drupal/seckit": "^2.0.3",
"drupal/shield": "^1.10",
"drupal/stage_file_proxy": "^4.0.0",
"drupal/storybook": "^1.0.4",
"drupal/testmode": "^2.8.0",
"drupal/xmlsitemap": "^2.0",
"drush/drush": "^13.8.0"
},
"require-dev": {
"behat/behat": "^4.0.0",
"dantleech/gherkin-lint": "^0.2.4",
"drevops/behat-screenshot": "^3.0.0",
"drevops/behat-steps": "^4.0@rc",
"drevops/phpcs-standard": "^1.1.0",
"drupal/coder": "^9.0.1",
"ergebnis/composer-normalize": "^2.54.0",
"friends-of-behat/mink-extension": "^3.0@alpha",
"lullabot/mink-selenium2-driver": "^1.7.4",
"mglaman/phpstan-drupal": "^2.2.2",
"mikey179/vfsstream": "^1.6.12",
"palantirnet/drupal-rector": "^1.1.3",
"phpcompatibility/php-compatibility": "^10.0@alpha",
"phpspec/prophecy-phpunit": "^2.5",
"phpstan/extension-installer": "^1.4.3",
"phpstan/phpstan": "^2.3.1",
"phpunit/phpunit": "^11.5.57",
"pyrech/composer-changelogs": "^2.2",
"softcreatr/jsonpath": "^0.10 || ^1.0",
"vincentlanglet/twig-cs-fixer": "^4.1.1"
},
"conflict": {
"drupal/drupal": "*"
},
"repositories": [
{
"type": "composer",
"url": "https://packages.drupal.org/8"
},
{
"type": "path",
"url": ".vortex/tooling",
"options": {
"versions": {
"drevops/vortex-tooling": "1.5.0"
}
}
}
],
"minimum-stability": "stable",
"prefer-stable": true,
"autoload-dev": {
"classmap": [
"tests/phpunit/"
]
},
"config": {
"allow-plugins": {
"composer/installers": true,
"cweagans/composer-patches": true,
"dealerdirect/phpcodesniffer-composer-installer": true,
"drupal/core-composer-scaffold": true,
"ergebnis/composer-normalize": true,
"php-http/discovery": true,
"phpstan/extension-installer": true,
"pyrech/composer-changelogs": true,
"symfony/runtime": true,
"tbachert/spi": true
},
"bump-after-update": true,
"discard-changes": true,
"platform": {
"php": "8.4.27"
},
"policy": {
"advisories": {
"block": false,
"audit": "fail"
},
"abandoned": {
"audit": "report"
}
},
"sort-packages": true
},
"extra": {
"drupal-scaffold": {
"file-mapping": {
"[project-root]/.editorconfig": false,
"[project-root]/.gitattributes": false,
"[web-root]/.csslintrc": false,
"[web-root]/.eslintignore": false,
"[web-root]/.eslintrc.json": false,
"[web-root]/.ht.router.php": false,
"[web-root]/.htaccess": false,
"[web-root]/INSTALL.txt": false,
"[web-root]/README.md": false,
"[web-root]/example.gitignore": false,
"[web-root]/robots.txt": false,
"[web-root]/sites/example.settings.local.php": false,
"[web-root]/sites/example.sites.php": false,
"[web-root]/update.php": false
},
"locations": {
"web-root": "web/"
}
},
"installer-paths": {
"web/core": [
"type:drupal-core"
],
"web/libraries/{$name}": [
"type:drupal-library"
],
"web/modules/contrib/{$name}": [
"type:drupal-module"
],
"web/profiles/contrib/{$name}": [
"type:drupal-profile"
],
"recipes/{$name}": [
"type:drupal-recipe"
],
"web/themes/contrib/{$name}": [
"type:drupal-theme"
],
"drush/Commands/contrib/{$name}": [
"type:drupal-drush"
],
"web/modules/custom/{$name}": [
"type:drupal-custom-module"
],
"web/profiles/custom/{$name}": [
"type:drupal-custom-profile"
],
"web/themes/custom/{$name}": [
"type:drupal-custom-theme"
]
},
"patchLevel": {
"drupal/core": "-p2"
},
"patches": {}
}
}
name
name
identifies the project in Composer's ecosystem, as a vendor name and a
project name joined by a slash. The installer replaces the template's
your_org/your_site with your organization and site machine names.
description
A short summary of the project's purpose. The installer fills in your site and organization names.
type
type sets how Composer, and any system that integrates with it, treats the
package, which can change how it's installed and used. Vortex sets it to
project, the type for an application rather than a reusable library.
license
license states the
project's license. Vortex sets it to proprietary, because the sites
built from the template are usually proprietary. The SPDX Open Source
License Registry lists the identifiers for
other licenses.
repositories
The repositories
section adds package repositories beyond Packagist, the default one. The
template declares the following 2 repositories:
| Repository | Type | Description |
|---|---|---|
packages.drupal.org/8 | composer | The official source for Drupal modules, themes, and distributions, which aren't published on Packagist. |
.vortex/tooling | path | Resolves the in-tree tooling package while developing Vortex itself. The installer removes this entry during site creation, so your project installs drevops/vortex-tooling from Packagist instead. |
require
The require section
lists the packages your project needs to run.
The Documentation column links to the page covering that package in more depth. A Settings link means Vortex ships a per-module override file that applies environment-aware defaults for that module. Some modules still need a running service or environment-specific values on top of those defaults.
Not every package reaches your project. The installer handles these packages based on your answers:
- It leaves out
drupal/storybook,drupal/migrate_plus, anddrupal/migrate_toolsunless you turn on Storybook or the migration database. - It drops the module of each service you deselect:
drupal/clamav,drupal/redis, ordrupal/search_api_solr. - It lets you deselect any of the other contributed modules except
drupal/search_api, which always stays.
➡️ See Contributed modules for what each override actually configures and where each module is installed.
The following table describes each package in require:
| Package | Description | Documentation |
|---|---|---|
php | The minimum PHP version required to run this project. Specify a range such as >=8.4 rather than an exact version such as 8.4.0. | None |
composer/installers | Installs packages into the correct location based on their package type, such as drupal-module, drupal-theme, or drupal-profile. | None |
cweagans/composer-patches | Patches Composer packages with git apply, incorporating fixes that aren't yet in an official release. Patch metadata and SHA-256 checksums are recorded in patches.lock.json for reproducible builds. | Patching |
drevops/vortex-tooling | Ships the Vortex operational scripts, such as the database, provisioning, deployment, and notification scripts, in vendor/drevops/vortex-tooling/src/. | Vortex tooling package |
drupal/clamav | Scans uploaded files for malware with the ClamAV engine before they're saved. | Settings |
drupal/coffee | Adds a keyboard shortcut to jump straight to any administration page by typing its name. | None |
drupal/config_split | Splits configuration into sets that are conditionally imported, enabling environment-specific configuration such as development-only modules. | Settings |
drupal/config_update | Provides tools and Drush commands to report, revert, and import configuration changes relative to the defaults shipped by modules. | None |
drupal/core-composer-scaffold | Copies Drupal's scaffold files, such as index.php and sites/default/default.settings.php, from the drupal/core package into the web root. The drupal-scaffold settings choose which files it manages. | None |
drupal/core-recommended | Pins the set of dependency versions that the Drupal community tests and recommends for a particular core version. | None |
drupal/devel | A suite of development tools for inspecting variables, entities, and the service container while debugging. | Settings |
drupal/drupal_helpers | A collection of helper functions that simplify writing update hooks and deployment operations. | Drupal helpers |
drupal/environment_indicator | Shows a colored banner identifying the current environment to prevent accidental changes on the wrong site. | Settings |
drupal/fast_404 | Answers requests for missing files with a 404 before Drupal bootstraps, saving the bootstrap that core's own fast 404 still performs. | Settings |
drupal/generated_content | Generates deterministic placeholder content from declarative definitions for development and testing. | Generated Content, Settings |
drupal/migrate_plus | Extends the core Migrate API with extra source and process plugins and configuration-entity migrations. | Migrations |
drupal/migrate_tools | Provides Drush commands and a UI to run, roll back, and monitor migrations. | Migrations |
drupal/navigation_extra_tools | Adds administration shortcuts (clear caches, run cron, run database updates) to the core Navigation module. | None |
drupal/pathauto | Automatically generates URL aliases for content based on configurable patterns. | None |
drupal/redirect | Manages URL redirects and creates them automatically when content URLs change. | None |
drupal/redis | Integrates Drupal with the Redis in-memory store for cache and lock backends. | Settings |
drupal/reroute_email | Reroutes all outbound email to a configured address on non-production environments to avoid emailing real users. | Settings |
drupal/robotstxt | Manages the robots.txt file from the admin UI, useful when it can't be placed on disk (for example, in multisite setups). Vortex leaves core's robots.txt out of scaffolding, so this module serves the file. | Settings |
drupal/sdc_devel | Development and validation tooling for Single Directory Components (SDC), reporting issues in component definitions and templates. | SDC Devel, Settings |
drupal/search_api | Provides a framework for building search experiences with pluggable indexing backends. | None |
drupal/search_api_solr | A Search API backend that indexes and searches content in Apache Solr. | None |
drupal/seckit | Adds configurable security-hardening HTTP headers, including Content Security Policy and anti-framing protection. | Settings |
drupal/shield | Protects non-production environments behind HTTP basic authentication. | Settings |
drupal/stage_file_proxy | Fetches media files from a remote site on demand, so local environments don't need a full copy of the files directory. | Settings |
drupal/storybook | Renders the custom theme's Twig stories through Drupal for the Storybook component library, so the library shows the same markup the site renders. | Storybook, Settings |
drupal/testmode | Filters the listings in registered views down to test content while test mode is on, which keeps live and generated content out of Behat assertions. | Testmode, Settings |
drupal/xmlsitemap | Generates a multilingual XML sitemap to help search engines index the site. | Settings |
drush/drush | A command-line shell and scripting interface for Drupal, providing a wide range of utilities to manage and interact with your Drupal sites. | Drush |
require-dev
The require-dev
section lists packages you need only during development, such as the code
quality and testing tools. The container image build runs
composer install --no-dev, so none of them reach production and the
deployment stays smaller. The installer removes the packages of each
development tool you deselect, with 2 exceptions: softcreatr/jsonpath
stays when you deselect Behat, and mikey179/vfsstream stays when you
deselect PHPUnit.
The following table describes each package in require-dev:
| Package | Description | Documentation |
|---|---|---|
behat/behat | A PHP framework for Behavior-Driven Development (BDD) that runs human-readable scenarios describing how your application behaves. The scenarios double as a shared description of the site for developers, stakeholders, and clients. | Behat |
dantleech/gherkin-lint | Lints the Gherkin feature files used in Behat tests, checking syntax and formatting for consistency. | Gherkin Lint |
drevops/behat-screenshot | Captures HTML and PNG screenshots on demand and whenever a scenario fails, and combines per-step screenshots into an animated GIF for each scenario. | Behat |
drevops/behat-steps | Provides the Behat extension that integrates the tests with Drupal, and a library of ready-made step definitions for Drupal sites. | Behat |
drevops/phpcs-standard | A PHP_CodeSniffer standard that checks the naming of local variables and parameters, snake case by default, and the naming and order of PHPUnit data providers. phpcs.xml applies it alongside the Drupal standards. | PHPCS |
drupal/coder | Provides the PHP_CodeSniffer rules for the Drupal coding standards. The 9.x line targets PHP_CodeSniffer 4.x. | PHPCS |
ergebnis/composer-normalize | A Composer plugin that normalizes the formatting and key order of composer.json. The CI lint job runs composer normalize --dry-run and fails on a file that isn't normalized. | None |
friends-of-behat/mink-extension | Connects Behat to Mink, providing the browser sessions and the base browser steps. Behat 4 needs its 3.x line, which composer.json requires as ^3.0@alpha. | Behat |
lullabot/mink-selenium2-driver | The Mink driver that controls a browser through a Selenium or WebDriver server. Behat uses it for scenarios tagged @javascript, and Drupal core's functional JavaScript tests build on it too. The installer removes it when you deselect Behat, even if you keep PHPUnit, so the functional JavaScript tests then need it required again. | Behat |
mglaman/phpstan-drupal | Adds Drupal support to PHPStan, so static analysis covers the hooks, services, and entities in modules and themes. | PHPStan |
mikey179/vfsstream | A virtual file system for PHPUnit tests, allowing file operations to be exercised without touching the real file system. | PHPUnit |
palantirnet/drupal-rector | Rector rules that rewrite deprecated Drupal code, making core upgrades more efficient. It installs rector/rector and constrains it to the versions its rule sets support. | Rector |
phpcompatibility/php-compatibility | PHP_CodeSniffer sniffs that check code for compatibility with specific PHP versions. The 10.x line adds support for PHP_CodeSniffer 4.x and is required with the @alpha stability flag. | PHPCS |
phpspec/prophecy-phpunit | Integrates the Prophecy mocking library with PHPUnit to provide advanced mocking capabilities in tests. | PHPUnit |
phpstan/extension-installer | Automatically registers the installed PHPStan extensions, removing the need to wire them up by hand. | PHPStan |
phpstan/phpstan | A static analysis tool that finds type errors, incorrect method calls, and other bugs without running the code. | PHPStan |
phpunit/phpunit | The PHP testing framework, used here for the unit, kernel, functional, and functional JavaScript tests. | PHPUnit |
pyrech/composer-changelogs | Prints a summary of package additions, updates, and removals after running composer update. | None |
softcreatr/jsonpath | A JSONPath implementation required by the drevops/behat-steps JSON assertion steps. The installer's Behat removal leaves it out, so it stays when you deselect Behat, although nothing else uses it. | Behat |
vincentlanglet/twig-cs-fixer | Checks and fixes Twig templates against a coding standard. | Twig CS Fixer |
conflict
The conflict section
declares every version of drupal/drupal, the standalone Drupal package,
incompatible with the project. Composer refuses to install it next to the
core packages, so core versions don't clash and core files stay consistent.
minimum-stability
The
minimum-stability
setting is the lowest stability that Composer accepts when it resolves
dependencies. Vortex sets it to "stable", so Composer ignores the
pre-releases of every package unless its constraint in require or
require-dev carries a stability flag. For example,
"friends-of-behat/mink-extension": "^3.0@alpha" lets that package install
as an alpha.
prefer-stable
The
prefer-stable
setting, when set to true, makes Composer choose a stable release over a
pre-release whenever a stable one satisfies the constraint. A requirement
with a stability flag, such as "drupal/config_update": "^2@alpha", then
gets an alpha only while no stable 2.x release exists. The same applies when
you lower minimum-stability to reach a feature or fix that's only in a
pre-release: every package that has a stable release keeps getting one.
config
The config section
configures how Composer behaves in the project. Vortex sets the
following keys:
allow-plugins: Lists the Composer plugins that are allowed to run. Composer doesn't run a plugin that isn't listed, which protects you from untrusted code in third-party plugins. Vortex allows these 10 plugins:composer/installerscweagans/composer-patchesdealerdirect/phpcodesniffer-composer-installerdrupal/core-composer-scaffoldergebnis/composer-normalizephp-http/discoveryphpstan/extension-installerpyrech/composer-changelogssymfony/runtimetbachert/spi
policy: Controls security auditing and version blocking of dependencies, and requires Composer 2.10.0 or later. Vortex setsadvisories.blocktofalse,advisories.auditto"fail", andabandoned.auditto"report". Advisories never block installs but still failcomposer audit, so vulnerabilities stay visible without breaking reproducible builds, and abandoned packages show up in the report without failing it. ➡️ See Dependency audit for the option values, ignoring advisories, and the CI integration.bump-after-update: Runscomposer bumpafter everycomposer update, which raises the version constraints incomposer.jsonto the installed versions. Vortex sets it totrueto bump all dependencies. The available values aretrue(all dependencies),false(disabled),"dev"(only development dependencies), and"no-dev"(only non-development dependencies).discard-changes: When set totrue, Composer discards local changes in dependencies that were installed from source, such as a Git checkout. The setting applies only when Composer runs non-interactively, for example in CI or with--no-interaction; an interactive run asks you what to do.platform: Tells Composer which PHP version to resolve dependencies for, regardless of the PHP version that runs Composer. Set it as an exact version number, such as the8.4.27that Vortex ships, and keep it in sync with the PHP version in the Docker containers.sort-packages: When set totrue,composer requirekeeps the package lists incomposer.jsonsorted by name. Sorted lists are easier to read and cause fewer merge conflicts. The setting doesn't affectcomposer.lock.
autoload-dev
The autoload-dev
section tells Composer how to autoload the classes that only development
needs, so no file has to include or require them by hand. Vortex
adds tests/phpunit/ to its classmap, which covers the project-level
PHPUnit tests, such as the settings tests, and their base classes.
extra
The extra section holds
configuration for Composer plugins, which read their settings from here to
fit the structure of your Drupal project. Vortex sets the following
keys:
-
drupal-scaffold: Controls the Drupal scaffold files:locations: Sets the web root (the directory containing theindex.phpfile),web/in Vortex.file-mapping: Decides which scaffold files the plugin manages. Vortex turns off 14 of the files that core provides: it ships its own.htaccess,.editorconfig, and.gitattributes, and leaves out others such asupdate.phpandrobots.txt. Set an entry tofalseto stop core from overwriting that file.
-
installer-paths: Sets where each package type installs:- Drupal core:
web/core - Contributed modules, themes, and profiles:
web/modules/contrib,web/themes/contrib, andweb/profiles/contrib - Custom modules, themes, and profiles:
web/modules/custom,web/themes/custom, andweb/profiles/custom - Libraries:
web/libraries - Recipes:
recipes - Drush command packages:
drush/Commands/contrib
➡️ See Overriding paths
- Drupal core:
-
patchLevel: Sets-p2fordrupal/core. The-poption of a patch command (for example,-p1or-p2) is the number of leading directories to strip from the file paths in the patch. Version 2.x ofcweagans/composer-patchesdoesn't read this key. It takes the depth from the first of these that's set:- The patch's own
depth extra.composer-patches.package-depthsfor the package- Its built-in default for the package, which is 2 for
drupal/core extra.composer-patches.default-patch-depth, which defaults to 1
- The patch's own
-
patches: Lists the patches to apply to each package, and it's empty in the template. The applied patch state lives in the generatedpatches.lock.jsonfile, which you commit likecomposer.lock. ➡️ See Patching