ibuildings/qa-tools
iBuildings QA Tools bundles common PHP quality checks into a single Composer package, with shared configuration and commands for code style, static analysis, and testing. It helps teams enforce consistent standards across PHP projects and streamline local development and CI workflows.
What it actually is. Despite the "Laravel/PHP package" framing, ibuildings/qa-tools is not a framework-integration package. It ships no service provider, no facade, no vendor:publish config. It is a Composer dev-dependency that bundles a 2017-era set of CLI QA tools (PHP_CodeSniffer, PHPMD, PHPCPD, PHPUnit, and related utilities) behind an installer binary (bin/qa-tools) that scaffolds opinionated config files (phpcs.xml, phpmd.xml, phpcpd, phpunit.xml) into a project. The durable asset is the config baseline, not the code.
Architecture fit. Confined to the developer-tooling layer, with zero runtime coupling to the Laravel application — no container bindings, no middleware, no autoload impact in production. Blast radius is limited to CI and developer machines, which is the one genuinely favorable characteristic. Unfortunately, the tooling layer is also the layer that ages fastest in any PHP estate.
Integration feasibility. Low for anything modern. Last release March 2017 predates PHP 7.2 stable and pins release-era tool versions (PHP_CodeSniffer 2.x, PHPUnit 4/5, PHPMD/CPD 2.x). Laravel 9+ requires PHP 8.0/8.1+, and those pinned tools cannot parse PHP 8 syntax — enums, readonly properties, constructor promotion, attributes, arrow functions, union/intersection types. Composer will either fail constraint resolution or install a stack that crashes on first invocation. No Laravel-specific integration work exists to salvage.
Technical risk. (a) Supply chain — archived upstream, zero dependents, no security-advisory response path for abandoned transitive dev dependencies; (b) correctness — parse failures on modern syntax masquerade as tool failures or, worse, as clean runs, eroding trust in the quality gate; (c) opportunity cost — the bundle has no PHPStan/Psalm/Larastan equivalent, so adopting it anchors the estate to a static-analysis-free baseline; (d) obsolescence — no PSR-12 ruleset, no PHP-CS-Fixer/Pint, no Rector, no PHPUnit 10/11 support.
Key questions for the requestor.
Stack fit. Treat the package as a reference implementation, not a dependency. The modern Laravel equivalent stack is: laravel/pint or PHP-CS-Fixer (formatting), PHP_CodeSniffer 3.x with slevomat/coding-standard (standards enforcement), phpstan/phpstan + larastan/larastan (static analysis — the gap qa-tools never covered), phpunit/phpunit 10/11 or Pest (tests), rector/rector (legacy code upgrades), and phpstan/phpstan-deprecation-rules. The duplicate-code function is now better served by PHPStan's duplicate-code detection or a maintained clone detector.
Migration path. Three options, in preference order:
company/qa-baseline Composer package with versioned rulesets.Compatibility. Requires a split CI matrix rather than a compromise: a legacy lane (PHP ≤ 7.1) could technically execute the bundled tools; the current lane (PHP 8.2/8.3) cannot. Do not lower the modern lane's PHP floor to accommodate a 2017 toolchain.
Sequencing.
Maintenance. Upstream maintenance is zero. Every fix, rule adjustment, and compatibility patch becomes ours. A shared baseline package needs a named owner and roughly a few days per quarter to track tooling major versions and ruleset drift. Modest but permanent.
Support. No vendor, no issue triage, no security advisories. Any incident — broken CI, a false positive blocking a release, a tool crash on new syntax — is debugged against unmaintained code. The predictable organizational failure is developer workarounds ("just exclude this sniff", per-project --ignore flags) that quietly hollow out the gate while it still appears green.
Scaling. Mechanically it scales fine — CLI tools in CI. Organizationally it does not: no plugin model, no per-team ruleset inheritance, no versioning of the baseline, and the installer's one-shot scaffolding model means configs diverge silently across repositories once run. A versioned internal Composer package scales across a growing repo estate; this does not.
Failure modes to instrument for.
Ramp-up. Developer learning curve is low — the underlying tools are familiar and configuration is declarative. The real cost is the transition itself: roughly 2–4 engineer-weeks to build and validate an owned baseline, plus a short comms and education push for teams moving off qa-tools artifacts. Legacy-lane engineers need explicit notice that the legacy lane is frozen and scheduled for retirement.
Recommendation. Do not add as a dependency. Approve a small, time-boxed spike to harvest its config presets into an owned, modern QA baseline, and treat the package itself as archived reference material. If a PHP 7.x legacy estate genuinely needs coverage this quarter, permit a forked copy in that lane only, with a documented exit date and no expansion beyond it.
How can I help you explore Laravel packages today?