Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Backward Compatibility Check Laravel Package

roave/backward-compatibility-check

A CLI tool that compares two versions of a PHP library and flags backward-compatibility breaks. It reads git tags and composer.json autoload paths, then fails CI builds when public API changes would break downstream consumers.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • Dev-only CLI tool with zero runtime footprint: it never ships in the application, adds no middleware/providers, and has no interaction with Laravel's container, HTTP kernel, or Eloquent. Architectural fit is therefore a release-engineering question, not an application-architecture question.
  • Value exists only where the codebase exposes a consumed API surface: first-party Composer packages, SDKs, Nova components, shared domain libraries, or open-source packages an organization publishes. For a monolithic Laravel application (controllers, jobs, models consumed only by itself), the tool has near-zero signal.
  • Mechanically it parses composer.json autoload paths, reflects two git revisions (default: latest SemVer tag vs. HEAD), and diffs the class-level API. It is complementary to PHPStan/Psalm (internal correctness) and conventional SemVer hygiene — it is the automated enforcement layer for the latter.
  • Hard prerequisites are all reasonable for a Laravel shop: git, Composer, autoload-declared source paths, committed changes, and x.y.z-format tags.

Integration feasibility

  • Low trial cost. Either composer require --dev roave/backward-compatibility-check plus one CI step, or the prebuilt nyholm/roave-bc-check Docker image with no local install at all.
  • Multiple output modes matter for the rollout: default console (non-zero exit → CI failure), --format=github-actions (inline PR annotations), and --format=markdown (drop-in changelog/release-note input). The last one is the underrated TPM lever — it converts the gate into release documentation.
  • .roave-backward-compatibility-check.xml supports regex-based baseline suppression of known/accepted breaks, which is what makes an incremental adoption path possible.
  • The one non-obvious operational constraint: CI must fetch full history and tags (fetch-depth: 0). Without tags, the base revision is wrong or unresolvable and the check silently loses meaning.

Technical risk

  • Dependency-graph conflict risk is the main technical hazard. The tool pulls composer/composer, roave/better-reflection, and symfony/console into the dev dependency graph. In a Laravel app with a locked Symfony/Composer set, a --dev install can force upgrades or fail resolution. Mitigation is strong and cheap: run it in an isolated job or via the Docker image rather than co-locating it in the application lockfile.
  • SemVer-tag dependency. Detection assumes a compliant tag trail. Repos using date-based tags, monorepo path tags, or hotfix branches will compare against the wrong base and produce either noise or false confidence.
  • False negatives are the expensive failure, not false positives: a missed break ships and a downstream consumer breaks in production. Gaps in autoload coverage cause classes to be skipped without any warning.
  • Baseline creep is a governance risk, not a tool risk — ignored-regex lists accumulate and quietly convert the gate into a no-op.
  • Ecosystem/adoption risk: 603 stars but 0 dependents and effectively single-organization stewardship (Roave). Release history shows heavy Renovate-driven dependency churn and recent feature additions (enum case detection, added-parameter detection), which means the tool's own matrix moves quickly.
  • Note the metadata anomaly: the listed last release date is in the future (2026-10-26) and the package score is moderate (45.97, opportunity 60.87). Treat "maintained and current" as an assumption to verify against the actual Packagist timeline before making it a blocking gate.

Key questions for the team

  1. How many of our repositories publish or share a consumed API? Which ones?
  2. Do we have a consistent, SemVer-compliant tag convention, and does CI fetch tags?
  3. Is our autoload section complete enough that reflection sees the whole public surface?
  4. Which PHP versions are in the CI matrix, and does the tool's constraint set cover them?
  5. Does composer/composer/symfony/console conflict with our locked versions — and if so, do we accept an isolated job/Docker runner?
  6. Who owns the baseline file, and what is the review SLA for adding an ignore rule?
  7. Do we want this as an advisory signal or a merge-blocking gate in the first quarter?
  8. How do we treat @internal symbols and test-only namespaces (scope suppression vs. baseline)?

Integration Approach

Stack fit

  • Composer + git + any CI (GitHub Actions, GitLab CI, Bitbucket). No Laravel coupling, no PHP-version surprise beyond the tool's own floor.
  • Best fit: internal shared packages consumed by multiple Laravel services, published SDKs, and open-source packages. Poor fit: application monoliths, and any repo where the "public API" is a REST/GraphQL contract rather than PHP classes (use schema diffing there instead).
  • Pairs naturally with existing quality gates as a distinct layer: unit tests (behavior), PHPStan/Psalm (internal types), BC check (external contract), Dependabot/Renovate (dependency surface).

Migration path

  • Phase 0 — Spike (1 repo, 1 week): add a non-blocking CI job on the highest-traffic shared package using --format=github-actions; collect the first report and measure noise level.
  • Phase 1 — Advisory: publish results as PR annotations only. No merge blocking. Build the initial baseline from legitimate exceptions; classify each suppressed entry as "intentional break" vs. "false positive" and document it.
  • Phase 2 — Enforce on release branches: make the check blocking on main/release branches for that package, with an explicit break-glass label.
  • Phase 3 — Fan out + document generation: extend to all published packages; wire --format=markdown into the release-notes template so changelogs are generated rather than hand-written.
  • Phase 4 — Policy: encode the rule in the release checklist ("major bump requires an empty BC report or an approved baseline delta").

Compatibility

  • Prefer the Docker/PHAR route (nyholm/roave-bc-check) or a dedicated tooling job to eliminate lockfile contention with Laravel's pinned Symfony and Composer versions.
  • Verify the tool's PHP constraint against the CI matrix before enforcing; running it only on the highest PHP version is usually sufficient and cheaper.
  • Ensure fetch-depth: 0 (or an explicit tag fetch) in every pipeline that runs it — this is the single most common silent misconfiguration.
  • For monorepos, run per-package with an explicit base/head pair rather than relying on repository-wide tags.

Sequencing

  1. Inventory repos with a consumed API surface; rank by downstream blast radius.
  2. Confirm tag convention and autoload completeness for the top 1–3 repos.
  3. Land the isolated, advisory CI job.
  4. Tune baseline; agree on ownership and review rules.
  5. Flip to blocking; add break-glass process.
  6. Fold into release docs and changelog generation.
  7. Extend to the remaining repos on a quarterly cadence.

Operational Impact

Maintenance

  • Near-zero production maintenance — the tool never runs in production. Ongoing effort is: pinned version bumps, periodic baseline review, and re-validating the CI job after PHP/Composer major upgrades.
  • Vendor churn is real (visible Renovate cadence, Symfony 7 work, security bumps to composer/composer); pinning and isolating the job absorbs almost all of it.
  • Budget roughly one engineer-hour per release per package for baseline triage, plus a quarterly 30-minute hygiene pass over accumulated ignore rules.

Support

  • MIT, community-supported, effectively single-organization stewardship (Roave) with a commercial support/audit offering. No SLA.
  • Risk mitigation is architectural, not contractual: keep the job isolated so a broken tool release can be skipped without blocking deploys, pin the version, and keep a documented "disable this gate" runbook.
  • Internal support burden is low — the failure messages are descriptive and the CLI is self-documenting via --help.

Scaling

  • Cost scales linearly with repository count, not traffic. Runtime is seconds to low minutes on typical package sizes; memory pressure appears on very large class graphs.
  • CI-minutes impact is negligible relative to a typical test suite. Monorepos require per-package invocation, which multiplies runtime — batch or restrict to changed packages.
  • No infrastructure to operate: no service, no database, no state beyond the baseline XML committed to the repo.

Failure modes and mitigations

Failure Impact Mitigation
Missing/unfetched tags Compares against wrong base; meaningless or noisy output fetch-depth: 0; assert the detected base version in job logs
Incomplete autoload coverage Classes silently skipped → false negative Audit autoload coverage as part of Phase 1
Baseline creep Gate becomes a no-op; real breaks ship Require PR review + justification per ignore rule; quarterly audit
Dev-dependency conflict CI job fails, blocks unrelated work Isolate via Docker/PHAR or dedicated tooling job
False positive on intentional break Release blocked Break-glass label + baseline entry, recorded in release notes
Upstream tool breakage Gate unavailable Pin version; runbook to disable gate without blocking delivery
Hotfix/patch branch semantics Base revision differs from intent Explicit base/head arguments in the hotfix pipeline

Ramp-up

  • Engineers: under an hour to run locally and read output; the --help and README cover the rest. No new language or framework to learn.
  • TPM/process effort dominates: roughly 1–2 days to define the policy (tag convention, baseline ownership, break-glass path, major-version discipline) and 2–4 weeks elapsed to move from advisory to blocking across the first cohort.
  • Organizational prerequisite worth flagging early: the tool only pays off if the team already intends to honor SemVer. It enforces a commitment; it does not create one.

KPIs a TPM should track

  • % of published packages covered by the gate.
  • Count of BC breaks caught pre-merge vs. reported post-release by consumers (target: post-release → zero).
  • Baseline ignore-rule count trend per repo (should be flat or declining).
  • CI job pass rate and mean runtime.
  • Changelog entries auto-generated vs. hand-written.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route