wyrihaximus/compress-contracts
PHP interfaces for compression. Defines small CompressorInterface and DecompressorInterface contracts so you can swap gzip, zlib, or custom implementations without coupling code to a specific library. Great for ReactPHP and other async projects needing clean, testable compression abstractions.
What the package is. wyrihaximus/compress-contracts is a single-purpose contract package: it ships a compress marker interface and nothing else. There is no service provider, no configuration, no runtime behaviour, no transitive dependency pull beyond the PHP platform itself. Published under MIT, versioned on Packagist, last tagged 2020-12-24. From a TPM lens this is closer to a naming convention with a composer manifest than to a library, and it should be evaluated as such: the decision is not "does this work" but "is this the right place for our type identity to live".
Architecture fit. The package is framework-agnostic by construction, which is either its entire value or its entire irrelevance depending on where we sit. In a ports-and-adapters Laravel codebase it maps cleanly onto the port half of the pattern: type-hint the marker in application service constructors, bind a concrete compressor in a service provider, keep the domain free of zlib or a cloud SDK. That is a legitimate architecture move and costs us almost nothing to wire. The counter-argument is that a marker interface carries no behavioural contract. PHP will let any class implements it and guarantee us nothing about method signatures, so the type hint buys identification, not safety. If the package truly contains only a marker (confirm, see questions below), the architectural benefit over a three-line interface in app/Contracts is negligible, and every external dependency carries a nonzero governance cost. Fit is good only if we are already consuming wyrihaximus/compress or another implementation in that author's async family, where the shared interface is the interop point.
Integration feasibility. Mechanically trivial: make composer-require "wyrihaximus/compress-contracts" per our project instructions, PSR-4 autoload resolves, one bind() call, done. No Laravel package discovery to audit, no publishable assets, no config merge to diff on upgrade. The real cost is the missing other half: this package gives us a name and expects someone else to give us behaviour. We would still be choosing, vetting, and testing a concrete compressor, and this contract does not narrow that field. Zero dependents on the registry means no reference implementations to borrow and no community proof that the interface shape survives contact with real adapters.
Technical risk. Blast radius is genuinely small because no code from this package executes at runtime; the worst case is a class-not-found or a PHP version constraint failure at install. The material risks are: (1) staleness. A 2020 release predates PHP 8.1 through 8.4, and the manifest's require.php may not admit our runtime, in which case the package is unusable without a fork; (2) abandonment. One maintainer, two stars, no releases in over four years, so any change we need is a fork we own; (3) supply chain. Every unmaintained package in the lockfile is an advisory surface even when it is inert; (4) semantic drift. If upstream ever adds a method to the interface, a minor bump silently breaks our implementors, and with no release cadence we would not see it coming. The 0.41 score is dominated by adoption signals rather than technical deficiency, which is the correct read here: the artefact is probably fine, but nothing about it is load-bearing.
Key questions.
composer.json, and does it admit our current and next runtime?App\Contracts, cost us materially more than adopting this one?Stack fit. Composer-native, PHP-only, no extensions required beyond whatever the eventual compressor needs. It will not touch Laravel's container, event loop, queue, or HTTP kernel. For our runtime targets (Laravel 11 on PHP 8.2+, optionally under Octane) the only gate is the platform constraint in the manifest, so that check precedes every other step. If the constraint excludes 8.2+, stop and treat this as a build-not-buy decision.
Migration path. Two clean routes. Route A, adopt: add the dependency, add a bind() in a dedicated CompressionServiceProvider, implement the interface in one adapter class wrapping the chosen compressor, inject the marker into consumers. Route B, build: declare an equivalent interface in app/Contracts with the same shape, no upstream dependency, and keep the door open to swapping in the package later because the surface is identical. Where we already have an internal compression interface, the migration is an alias step: adapter class implements both, consumers move over in one PR, internal interface is deleted once usage is zero. Neither route requires a data migration, a config change, or a deploy ordering constraint.
Compatibility. Verify the PHP constraint against our actual matrix rather than the README. Confirm there is no extra.laravel block, since a package claiming discovery that we do not want would need suppressing. Because the artefact is stateless and holds no properties, Octane worker reuse and long-running processes are unaffected; nothing accumulates between requests. Serialization is a non-issue, so queued jobs carrying a compressor reference can rely on container re-resolution.
Sequencing. (1) Read composer.json and the interface file directly, confirm marker status and PHP constraint. (2) Decide adopt versus build; default to build unless an implementation already depends on this contract. (3) If adopting, land the dependency and the interface implementation in a single PR with a container binding test. (4) Add a contract test asserting every implementor satisfies our expected call shape, since the marker itself will not. (5) Pin the version explicitly and record the abandonment risk and fork owner in the dependency register. (6) Defer any refactor of existing compression call sites to a follow-up, so the dependency addition is independently revertible.
Maintenance. Effectively zero code churn: an interface does not rot the way an implementation does. The maintenance burden is administrative, not technical, and it lives in the dependency register: an unmaintained package with no release in four years needs a named owner, a fork contingency, and a review trigger on our next PHP upgrade. Budget the effort as a few hours at PHP-major-upgrade time, not as a recurring cost.
Support. No vendor, no SLA, no paid tier. Support is a GitHub issue tracker behind a single maintainer. For a package whose entire contribution is a type declaration, that is acceptable; for anything we would need changed upstream, it is effectively zero. Set expectations accordingly: we support this, not them.
Scaling. No runtime footprint at all, so no impact on throughput, memory, or cold start. The compressor we bind behind it is where all scaling characteristics live (CPU for gzip, latency for a cloud round trip), and those decisions should be reviewed on their own merits. Adopting this contract neither helps nor hinders horizontal scaling.
Failure modes. Class-not-found after a composer prune or autoload regression, caught immediately by any boot test. Install failure on a new PHP minor, caught in CI before merge. Silent behavioural breakage if upstream later adds methods to the interface, which is why the pinned constraint plus a contract test matters. Type confusion where an implementor satisfies the marker but violates our expected call shape, again caught by the contract test rather than by the interface. The worst realistic outcome is a stale lockfile entry that blocks a PHP upgrade at an inconvenient moment, which is mitigated by resolving the build-versus-buy question now rather than at upgrade time.
Ramp-up. Near zero for engineers: one interface, one binding, one adapter. The actual ramp-up cost is explanatory, since a new joiner will reasonably ask why a marker interface is a dependency at all, and the answer needs to be a one-liner in the dependency register or an ADR. If that answer cannot be written in one sentence, that is the signal to build the interface in-house and delete the dependency.
How can I help you explore Laravel packages today?