yahnis-elsts/plugin-update-checker
A PHP library that lets WordPress plugins and themes check for updates from GitHub, GitLab, Bitbucket, or a custom update server. It hooks into the native WordPress update system so users see and install new versions just like plugins hosted on WordPress.org.
Architecture fit. This is not a Laravel package in any meaningful sense — it is a WordPress-runtime library. It has no service provider, no publishable config, no facades, and no framework contracts. It attaches itself to WordPress's update pipeline via pre_set_site_transient_update_plugins, plugins_api, site_transient_update_themes, and WP-cron. Its "architecture," such as it is, is a set of versioned class trees (Puc\v4\…, YahnisElsts\PluginUpdateChecker\v5\…) plus a bundled compatibility layer. Fit is therefore binary: it is a strong fit if and only if one of our deliverables is a distributed WordPress plugin or theme. If the Laravel application is the product and there is no WP artifact in the portfolio, the package is out of scope and should be rejected at intake regardless of its quality.
The realistic reason a Laravel shop would carry this dependency is the second, more interesting role: our Laravel app acts as the update server — publishing release manifests, gating downloads by license key, and serving signed S3 URLs — while PUC lives inside the WordPress plugin we ship to customers. That is a legitimate and well-trodden pattern, and it makes PUC a de facto contract specification for our own API.
Integration feasibility. High, with caveats. The library is MIT-licensed, self-contained, and vendorable; drop-in adoption in a plugin bootstrap is roughly ten lines. The friction is not in wiring it up but in distribution discipline: PUC must be present in the built artifact shipped to customers, so our CI must run a no-dev Composer install and commit/vendor the library into the release zip. Pulling it at runtime on customer sites is not viable — many WordPress hosts are read-only or have no Composer, and Composer isn't a WP deployment mechanism.
Technical risk. The dominant risk is that PUC is, by design, a remote code execution channel into every customer site we serve. Compromise of our manifest host, our Git host, or our release pipeline converts directly into arbitrary code pushed to the entire install base. PUC performs no signature verification and no integrity check beyond TLS. That is acceptable for a v1 but must be a deliberate, documented acceptance, with a hardening roadmap (pinned host, immutable release assets, signed manifests verified out-of-band, staged rollout).
Secondary risks: a single-maintainer project (bus factor of one) with a v4→v5 namespace churn history and no LTS commitment; token leakage if we ever embed GitHub credentials in a distributed zip (never do this — proxy through our Laravel API instead); GitHub's unauthenticated 60-requests-per-hour-per-IP ceiling, which is easily saturated by agency/multisite hosting where dozens of sites share one egress IP; and duplicate-class collisions when a customer site runs several plugins each vendoring a different PUC major version.
Key questions. (1) Do we ship a WP plugin/theme to third parties — yes or no? (2) Public repo, private repo, or our own manifest endpoint? The answer determines the entire secrets model. (3) Do we need license-gated updates and beta/stable channels? (4) Are we also listed on WordPress.org — because PUC deliberately stands down when the plugin slug exists there, so co-publishing silently disables our update path. (5) What minimum PHP and WP versions do we support, and does PUC's floor sit below ours? (6) Who owns the update path in an incident, and how fast can we publish a forced fix?
Stack fit. Treat the dependency in two tiers. In the Laravel monolith, add yahnis-elsts/plugin-update-checker only inside the WordPress plugin's own Composer manifest — not in the application's require block, where it would be dead weight and pollute the dependency graph. In the plugin repository, it is a first-class production dependency pinned to an exact version. Because Packagist dependent counts are near zero, we get no ecosystem signal from the package itself; version safety comes from our own pin, not from community pressure.
Migration path. If a homegrown updater exists, PUC replaces only the client-side hook layer; the distribution backend survives intact and becomes simpler. Define the manifest JSON as our public contract (version, download_url, requires, requires_php, tested, sections, banners, upgrade_notice) before writing any code, because that schema is what we will be supporting for years. If we are on PUC v4, migrate to v5 now behind an adapter class in our plugin so the namespace churn never leaks into business logic — v5 is the maintained line and the compatibility shim is a liability, not an asset.
Compatibility. Confirm PUC's PHP and WordPress floors sit at or below our plugin's declared minimums, and pin CI to a matrix covering the oldest supported PHP plus current WordPress. Verify behavior under multisite network activation, WP-CLI (wp plugin update --all), and the auto-update UI toggle. Confirm the plugin's directory slug matches the manifest slug exactly — a mismatch produces silent no-op updates that are painful to diagnose in the field.
Sequencing.
Maintenance. Low code churn, moderate attention cost. Budget one to two engineering days per quarter to review upstream releases, run the update-path regression, and re-pin. The MIT license means we can fork if the maintainer walks, but a fork means we now own a security-sensitive component — a real, if unlikely, cost to record in the risk register.
Support. Expect a shift in ticket taxonomy from "cannot install" to "update did not apply." PUC ships a debug mode that dumps update-check state; wrap it behind an authenticated query flag and document it in the support runbook so tier-one can capture diagnostics in one round trip. Without that, these tickets consume disproportionate senior time.
Scaling. The client side scales fine — checks are transient-cached and cron-driven. The server side is trivially cheap (static JSON behind a CDN); the constraint is the third-party API ceiling if we point PUC at GitHub directly. Serving the manifest from our Laravel app instead gives us rate-limit independence, per-license gating, and release telemetry, and is worth the modest build. Watch WP-cron on low-traffic sites: checks are traffic-triggered, so quiet installs may lag days behind. Also guard against slow update checks blocking wp-admin if caching is misconfigured.
Failure modes. Silent update failure (slug mismatch, stale transient, TLS interception on managed hosts); expired or revoked auth tokens; manifest schema drift breaking older clients; GitHub outage or rate limiting; the plugin being simultaneously listed on WordPress.org, which disables PUC entirely; duplicate bundled versions colliding on class definitions; and the worst case, a bad release auto-applied at scale with no rollback primitive in PUC and a PHP fatal that locks admins out of their own sites. Mitigations: staged rollout via release channels, retain every prior zip for manual reinstall, ship a upgrade_notice and a compatibility guard, and keep a documented emergency-publish procedure with a target time.
Ramp-up. One engineer reaches productivity in two to three days; the README is genuinely good for the consumer side. The gap is the producer side and the Laravel-side publisher, which have no upstream documentation and need an internal design note plus a runbook covering publish, rollback, token rotation, and incident response. Train at least two people — this component sits on the critical path for every security patch we will ever ship to WordPress customers, and a single trained engineer is an unacceptable concentration of risk.
How can I help you explore Laravel packages today?