roots/bedrock-autoloader
Bedrock Autoloader bridges Composer and Bedrock-based WordPress installs, letting plugins installed via Composer be autoloaded instead of manually managed, keeping dependencies declarative and deployments simpler.
Architecture fit
roots/bedrock-autoloader is a small, single-purpose Composer package that sits at the WordPress mu-plugin bootstrap layer of the Roots Bedrock stack. It is not Laravel framework code and does not depend on the Laravel container — it is a plugin-loading primitive that coexists with Bedrock/Sage/Acorn deployments. The v2.0.0-beta.1 redesign (side-effect-free constructor, injected WPMU_PLUGIN_DIR, explicit boot()/markLoaded() lifecycle) is a genuine architectural improvement: it converts an implicitly-bootstrapping class into something that can be constructed, tested, and — if desired — bound in a Laravel/Acorn service provider. The cost is that every consumer must now supply the mu-plugin path and drive the lifecycle explicitly, so the upgrade is a code change, not a version bump.
Integration feasibility
Feasible for any Bedrock project already using Composer autoloading at mu-plugin load time. The new mu-plugins/bedrock-autoloader.php shim is the intended integration point and is self-contained: it guards on is_blog_installed() and class_exists(), then includes files returned from boot(). Non-Bedrock WordPress installs, or installs where vendor/autoload.php is not loaded before mu-plugins, will need bespoke wiring. Beta status means the public API (boot() return type, markLoaded() semantics) may still shift before GA.
Technical risk
Roots\Bedrock\Autoloader) — any first-party or agency-maintained code, mu-plugin, or Bedrock fork referencing the old class name will fatal or silently no-op. No compatibility alias is announced.class_exists() guard means a missing/renamed class causes autoloaded plugins to simply not load, with no error. That is a low-observability, high-blast-radius failure mode.$GLOBALS/$wp_filter at include time — plugins that implicitly relied on the old scope could behave differently.Key questions
boot() idempotent, and what does it return (array vs. generator)? What happens if it throws mid-iteration?markLoaded() write persistent state (options/transients), and is that safe on every request and under multisite?WPMU_PLUGIN_DIR is filtered/overridden by a host or plugin?Stack fit
Fits Bedrock-based WordPress (Composer-managed core, web/app/mu-plugins/, WP-CLI workflows) and composes cleanly with Sage/Acorn themes and Acorn service providers. It is orthogonal to the Laravel application layer — treat it as infrastructure, not application code. Projects on vanilla WordPress or non-Composer deployments are out of scope without custom bootstrap wiring.
Migration path
^1.1.0 until beta validation completes; consume 2.0.0-beta.1 only in a staging/canary environment.bedrock-autoloader.php shim verbatim (do not fork it — forks are the main upgrade liability here).Roots\Bedrock\Autoloader and the new constructor/lifecycle signature.composer dump-autoload and verify wp plugin list still shows the asterisk marker on autoloaded plugins.Compatibility
PHP 8.2+; Composer 2.x; requires WPMU_PLUGIN_DIR to be defined (standard in Bedrock); depends on is_blog_installed() so it is safe pre-install. Verify the target Bedrock version documents the same mu-plugin path convention.
Sequencing PHP runtime upgrade → staging rollout with beta pinned → smoke test plugin load order, autoloaded-plugin markers, and any plugin relying on global scope at include time → single-environment canary in production for one release cycle → widen to remaining environments → move to GA tag when published.
Maintenance Very low surface area (~one class, no runtime dependencies) and Laravel Pint adoption signals active code-quality hygiene. The real maintenance cost is tracking an upstream beta and keeping the shim file unmodified — internal forks are the primary long-term liability.
Support Community-supported via Roots' GitHub and Discord; no vendor SLA or paid escalation path. Assign a named internal owner for the shim file and the PHP version floor, since failures present as "plugins missing," not as autoloader errors.
Scaling Runtime cost is a single filesystem scan of the mu-plugins directory per request — negligible at typical plugin counts, but worth measuring if the directory grows large or on high-traffic, full-page-cached-disabled sites. Multisite behaviour and per-site plugin activation semantics should be explicitly tested rather than assumed.
Failure modes
class_exists() guard fails → autoloaded plugins silently absent.markLoaded() timing relative to a partial boot() failure → potentially inconsistent "loaded" state.
Recommend an observability hook: a WP-CLI check or health probe asserting that expected autoloaded plugins appear in wp plugin list.Ramp-up Low technical ramp-up — one class, readable in under an hour — but it requires working knowledge of the WordPress mu-plugin lifecycle and Bedrock's directory/autoload conventions, which is where most of the onboarding time goes. Budget a half-day for an engineer unfamiliar with Bedrock, plus the staging validation cycle.
How can I help you explore Laravel packages today?