This Composer plugin makes PHP_CodeSniffer standards install themselves
Composer installer for PHP_CodeSniffer coding standards
At a glance
- What is it?
- PHPCSStandards/composer-installer is an MIT licensed Composer plugin that finds phpcodesniffer-standard packages in your installed dependencies, scans them for rulesets and points PHP_CodeSniffer's installed_paths option at the result, which removes the symbolic links and manual configuration that installing coding standards otherwise needs. The cost is that it is a Composer plugin, so it needs explicit permission to run.
- Who is it for?
- Adopt this plugin if your team installs PHP_CodeSniffer standards through Composer and has ever had to symlink a vendor directory or edit installed_paths by hand, because the plugin does that wiring on every install. Do not adopt it if your standards are installed some other way, or if you cannot allow Composer plugins to execute in your build, since the permission is a prerequisite rather than a preference.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem is installed_paths and where the rulesets live
The plugin exists because installing PHP_CodeSniffer coding standards through Composer is otherwise fiddly. The README puts it plainly: no more symbolic linking of directories, checking out repositories on specific locations or manually changing the phpcs configuration. That is the real problem, and it is worth understanding why it exists. PHP_CodeSniffer finds its rulesets by looking in a configured list of paths, and the standard packages that Composer installs live inside vendor directories whose layout depends on which packages happen to be installed. A project with two standards therefore ends up with a path that changes whenever a dependency moves, and the fix, a symlink or a hand edited configuration file, is a piece of local state that nobody else has. The plugin removes that state by making the paths a function of what is installed.
Composer 2.2 turned plugins into something you have to allow
Installation is a development dependency, as Composer requires for a tool used at build time:
composer require --dev dealerdirect/phpcodesniffer-composer-installer:"^1.0"Since Composer 2.2, Composer asks for permission to allow this plugin to execute code, and the README is clear that for the plugin to be functional, permission needs to be granted. When it has been, Composer adds a snippet to the composer.json file automatically:
{
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}You can add the permission flag yourself, and the README says you can safely do so to avoid Composer needing to ask, by running:
composer config allow-plugins.dealerdirect/phpcodesniffer-composer-installer trueThis is the single most important operational detail in the whole plugin. A team that adds the package to composer.json and then runs a build in a non-interactive environment gets a permission prompt or a refusal, and the symptom is that the standards are not found, which looks like a broken plugin rather than a missing permission.
Three steps, and a list of standards you can check
The plugin runs a short sequence. It searches for phpcodesniffer-standard packages in all of your currently installed Composer packages. Matching packages and the project itself are then scanned for PHP_CodeSniffer rulesets. Finally, the plugin calls PHP_CodeSniffer and configures the installed_paths option. The result is verifiable, and the README shows the check. With an example project that includes multiple phpcodesniffer-standard packages, after running composer install PHP_CodeSniffer just works, and the listing command reports what is installed:
$ ./vendor/bin/phpcs -i
The installed coding standards are PEAR, PSR1, PSR2, PSR12, Squiz, Zend, PHPCompatibility, Modernize,
NormalizedArrays, Universal, PHPCSUtils, WordPress, WordPress-Core, WordPress-Docs and WordPress-ExtraThat list is worth reading twice, because it shows the plugin pulling in the transitive standards as well as the ones you asked for. PHPCompatibility and Modernize come from the PHPCompatibility package, and the WordPress standards from the WordPress coding standards package, so a project that requires two standards ends up with six available.
The compatibility matrix is narrow and moving
The plugin declares compatibility with three things, and the README annotates each with the version where support changed. For PHP it supports 7.2 and 8.x, with support for PHP 8 available since v0.7.0 and support for PHP below 7.2 dropped in v1.3.0. For Composer it supports 2.2 and newer, with Composer 2 support since v0.7.0 and support for Composer below 2.2 dropped in v1.1.0. For PHP_CodeSniffer it supports 3.x and 4.x, with version 4 support available since v0.7.0 and version 2 support dropped in v1.2.0. The practical consequence is a floor and a ceiling. If your project is on PHP 8.2 with PHP_CodeSniffer 4 and a current Composer, you are inside the supported range. If anyone in the estate is still on PHP 7.1 or Composer 2.1, the plugin will not help them, and the old manual procedure remains necessary for those environments. The version numbering in the annotations also hints at a moving target, since the PHP 7.2 drop is described as landing in v1.3.0 while the most recent release listed is v1.2.1.
Calling the plugin by hand, for CI and for development
In some circumstances it is desirable to call the plugin's functionality directly, and the README gives the instance: during development or in CI environments. The catch is that the plugin requires Composer to work, so direct calls need to be wired through a project's composer.json, by adding a call to the Plugin::run function in the script section. The script can then be called with composer run-script install-codestandards, and the README shows how to reference it from other script configurations, in this case a post-install-cmd entry that invokes the install-codestandards script. The reason this matters is that a Composer plugin's normal execution points are install time, and a CI system that prepares the vendor directory in a separate step, or a developer who has already installed the dependencies, needs a way to trigger the standards wiring on demand rather than waiting for the next install.
Search depth and the global plugin trap
Two small settings are worth knowing about. By default the plugin searches up for coding standards three directories deep, which in most cases should be sufficient, but the depth can be customised. To change it you add an extra key to the project file:
{
"extra": {
"phpcodesniffer-search-depth": 5
}
}The second is a caveat rather than a setting. When the plugin is installed globally, Composer will load the global plugin rather than the one from the local repository. The README notes that this behaviour is documented in the Composer manual, and that it could potentially confuse, as another version of the plugin could be run and not the one specified by the project. That is a sharp edge for shared build images and for developer machines where someone has run a global composer require, and it is the sort of thing that produces a bug report which turns out to be a configuration question.
Publishing your own standard to the same registry
The README also covers the other direction, a team that wants to distribute its own coding standard through the same mechanism. A coding standard can be developed normally, as the PHP_CodeSniffer documentation describes, and a Composer package for it is created by adding a composer.json file:
{
"name" : "acme/phpcodesniffer-our-standards",
"description" : "Package contains all coding standards of the Acme company",
"require" : {
"php" : ">=7.2.0",
"squizlabs/php_codesniffer" : "^4.0"
},
"type" : "phpcodesniffer-standard"
}Three requirements follow. The repository may contain one or more standards. Each standard can have a separate directory no deeper than three levels from the repository root. And the package type must be phpcodesniffer-standard, because without that the plugin will not trigger. There is one more piece of advice, and it is the subtle one. If your standard depends on additional external PHPCS standards, this plugin can install all of them for your end users, yours and their dependencies, which reduces the number of support questions about installed_paths and simplifies your installation instructions. For that to work the external standard must add the plugin to its composer.json via require, not require-dev, and the version requirement should stay flexible, because Composer treats unstable minors as majors and cannot resolve one config requiring the plugin at version ^0.7 against another requiring ^1.0.
Editorial conclusion
Adopt this plugin if your team installs PHP_CodeSniffer standards through Composer and has ever had to symlink a vendor directory or edit installed_paths by hand, because the plugin does that wiring on every install. Do not adopt it if your standards are installed some other way, or if you cannot allow Composer plugins to execute in your build, since the permission is a prerequisite rather than a preference. Before you roll it out, check the version constraints your standards require, since the plugin only supports PHP 7.2 and newer, Composer 2.2 and newer, and PHP_CodeSniffer 3.x and 4.x, and read the caveat about globally installed plugins before you add it to a shared build image.
Frequently asked questions
What does the PHPCSStandards composer-installer plugin do?
It searches for phpcodesniffer-standard packages among your installed Composer packages, scans the matching packages and the project itself for PHP_CodeSniffer rulesets, then calls PHP_CodeSniffer to configure the installed_paths option. That removes the need to symlink directories or edit the phpcs configuration by hand.
How do I install the composer-installer plugin?
Require it as a development dependency with composer require --dev dealerdirect/phpcodesniffer-composer-installer:"^1.0". Since Composer 2.2 the plugin needs explicit permission, which Composer adds to the allow-plugins block in your composer.json, or you can set it yourself with composer config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true.
Which versions of PHP, Composer and PHP_CodeSniffer are supported?
PHP 7.2 and 8.x, with support for PHP below 7.2 dropped in v1.3.0; Composer 2.2 and newer, with support for Composer below 2.2 dropped in v1.1.0; and PHP_CodeSniffer 3.x and 4.x, with version 2 support dropped in v1.2.0. Support for PHP 8, Composer 2 and PHP_CodeSniffer 4 all became available in v0.7.0.
How do I publish my own coding standard for the plugin to install?
Add a composer.json file to the repository with the type set to phpcodesniffer-standard, because without that type the plugin will not trigger. The repository may contain one or more standards, and each standard can have its own directory no deeper than three levels from the repository root. If the standard needs other PHPCS standards, require this plugin in require rather than require-dev so that your users get them installed as well.
Can I trigger the composer-installer plugin outside of composer install?
Yes, and the README suggests it for development and in CI environments. Because the plugin requires Composer to work, a direct call has to be wired through the project's composer.json by adding a call to the Plugin::run function in the scripts section, and the script is then run with composer run-script install-codestandards or referenced from another script such as post-install-cmd.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/phpcsstandards-composer-installer)Was this useful?