[Obsolete] Composer package naming conventions
This documentation is deprecated.
The standards have moved to GitLab pages, Drupal coding standards.
With Drupal adopting Composer as dependency manager, the community has to follow a naming convention for composer package names to avoid conflicts. How you define your own package with a composer.json can be found in Add a composer.json file to define your module as a PHP package. In general, Composer only allows for package names like so: vendor/project. You cannot use more than two levels. This leads to the following conventions.
Drupal Projects
Composer uses its own type of registers to track millions of different packages; usually, these are referred to as "Composer repositories" (to avoid any confusion with "Git repositories," which are slightly different things). The factory default Composer repository is seen on Packagist.org, but there can be an unlimited number of such Composer repositories publicly available on the Internet. The Drupal community also has its own: the https://packages.drupal.org/8 service has no graphical interface as it is not meant for browsing manually from a web browser.
The vendor part
Having several independent registers out on the Internet brings the risk of namespace conflict: when two separate repositories would offer two different software packages with the same name of great-vendor/fantastic-package. To avoid such collisions, the global Composer ecosystem applies some countermeasures. The Drupal community has the vendor name "drupal" reserved for itself. Therefore, all software packages available for download from our https://packages.drupal.org/8 Composer repository must have "drupal" as the first part of their name.
The package name part
As you can see from the above, all software packages within all repositories must also have individually identifiable names. Once the first part, "drupal/", is commonly shared by all in our repository, the second part of the name must be unique. Fortunately, the Drupal ecosystem already has such a distinct naming convention as the "machine names" of modules, themes, and profiles. Thus, using these internally already used machine names as the second part of the Composer package names also seems obvious. An important note here: although the hyphen ("-") is more common for separating words in Composer vendor and package names, Drupal's machine names use an underscore ("_") for this instead. For example, if you have your contrib module called "My Module" as its human label, then its machine name used within the Drupal world will be derived as "my_module" probably (not mandatory, but recommended). Finally, its package name in Composer's global namespace derives from the machine name and becomes drupal/my_module (required to match).
In Drupal.org URLs
When we said that our own Composer repository at https://packages.drupal.org/8 is not meant for manual browsing, it's important to note that Drupal.org's project browsing features (the search forms on /project_module or /project_theme) replace that functionality. Whenever you navigate to a dedicated page of a given project (like drupal.org/project/admin_toolbar, for example), the very same machine name of the project appears in the URL path after https://drupal.org/project/… as well. Seeing such a URL, you can be almost 100% certain that the package name of that contrib module is probably drupal/admin_toolbar. This general thumb rule for matching Composer package names with Drupal machine names makes the daily work of site builders and developers maintaining Drupal websites much easier. If you are interested about the historical discussions related to establishing this naming convention back in 2015, you can read more here.
Some extraordinary cases
- Drupal itself is a project: drupal.org/project/drupal →
drupal/drupal- But Core is a subtree of Drupal: drupal.org/project/core →
drupal/core
- But Core is a subtree of Drupal: drupal.org/project/core →
- Datetime is a module within Drupal Core: drupal.org/project/datetime →
drupal/datetime - Views in Drupal 7 was a contrib project: drupal.org/project/views →
drupal/view, but today is part of Drupal core
Some project URLs are not accessible or point to another project, as they are reserved names. In most cases those are sub-modules or sub-themes of existing projects, like Drupal core.
Drupal (Sub-)Modules, Themes and Profiles
Multiple modules, themes and profiles might be part of a single Drupal project, for example system, node, standard in Drupal or page_manager, views_content in ctools. As Drupal won't let you run two modules with the same name, modules, themes, profiles and Drupal projects share the same namespace.
Convention
Sub-modules, -themes and profiles must use the package name.
drupal/SUBPROJECT
where SUBPROJECT is the machine name of the module, theme or profile.
This will not conflict with drupal/PROJECT, as Project names share the same namespace with modules, themes and profiles due to the way Drupal works.
Over time, some projects may merge into or were split from another project. For example Views was merged into Drupal 8 or Page Manager was separated from ctools for a Drupal 8 release. Because of different version numbers, these cases can be resolved by utilizing Composer's replace property and/or using different composer repositories.
In the case naming conflicts cannot be resolved, Drupal Projects shall take precedence over (sub-)modules, themes and profiles.
For avoiding dependency issues, Drupal projects declaring their own composer.json, should also add their submodules and -themes to the replace-section.
Examples
- Module
devel_generatefrom Devel →drupal/devel_generate - Drupal 8 core's Views module can be specified as
drupal/views, but the dependency will be resolved as a contrib replacement bydrupal/core.
Based on this convention, meta-packages or subtree-splits could be provided for every module, theme and profile.
Components
Drupal projects may also contain custom components (like PHP libraries). As those components are not bound to any namespace, they are likely to conflict with a given Drupal project, module, theme, etc..
Convention
Package names must be prefixed with their parent's name and a dash (-), in the case it will use the drupal/ vendor:
drupal/PARENT-COMPONENT
where PARENT is the name of the parent package and COMPONENT a sufficient name for the component.
Since the - (dash) is not used in the existing drupal namespace, it shouldn't conflict in anyway to what is currently in Drupal.
Examples
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
Still on Drupal 7? Security support for Drupal 7 ended on 5 January 2025. Please visit our Drupal 7 End of Life resources page to review all of your options.