php-standard-library/foundation
Foundation provides the core building blocks for PHP Standard Library packages: a consistent exception hierarchy, the Ref reference wrapper for safe value passing, and invariant functions for validating preconditions and enforcing assumptions. Lightweight, dependency-free, and designed for reuse acr...
Build vs buy for a shared primitive layer. The recurring "build vs buy" argument for internal utilities — exception hierarchies, typed ID wrappers, runtime assertions — can be settled by adopting a small, MIT-licensed dependency instead of maintaining an in-house app/Support package. The scoping rule matters more than the library: buy the primitives, build the domain.
Standardizing the failure contract. A shared base domain exception plus invariant() gives every service one way to fail with intent, which the HTTP layer maps to a canonical error payload (Problem Details / RFC 7807). That is a product decision about API consistency and client-facing behavior, not a code-style preference.
Enabling incremental DDD / modular monolith work. Ref provides typed identifiers (UserId, OrderId) so IDs cannot be crossed at boundaries, and invariant() enforces value-object rules at the edges. This supports a roadmap item that's otherwise hard to sequence: isolating a domain layer without a big-bang rewrite.
Making "what should happen when X is invalid" explicit. A documented set of exception types and invariants is a readable specification. It shrinks review ambiguity and shortens onboarding for new engineers.
What it explicitly does not unlock — and should not be sold as unlocking — is collections, string helpers, validation rules, or HTTP concerns. It is a narrow slice of a larger standard-library effort, and conflating the two inflates the business case. The 1-star/0-dependent profile also means it is a liability as a dependency in a public SDK, not a credibility signal.
A decision it forces. Whether you are willing to pin a version, vendor the source, and own patches. If yes, this is a cheap consistency win. If no, the discussion is over.
Adopt when:
Look elsewhere when:
App\Exceptions\Handler and Illuminate\Support — marginal value approaches zero.Decision rule: if the pilot cannot be delivered inside a sprint in a single module with a defined rollback and explicit kill criteria, decline.
To executives: frame it as a small, reversible risk-reduction move — not a platform bet. One MIT dependency, limited surface area, adopted in one module first, removable in a day. The outcome is a single, consistent error payload for API consumers and the removal of duplicated glue code across teams. Avoid the phrase "standard library"; say "one way to fail, one way to pass IDs, across N services." State the bus-factor risk plainly and pair it with the mitigation (pinned version, vendored source, internal ownership) so the ask reads as disciplined rather than optimistic.
To engineering: position it as a vocabulary, not a framework. Use Ref and invariant() at boundaries, map domain exceptions once in the exception handler, and leave Illuminate untouched for everything else. Treat upstream as a reference implementation worth copying: vendor the source, add a PHPStan rule to keep the conventions enforced, and accept that you will carry patches. Define the pilot up front — one module, one error contract, duplicated classes deleted, no behavioral regressions.
To product and roadmap: fund an enablement slice, not a migration program. Success is measured by duplicates removed, contract consistency, and onboarding time — not by adoption percentage. Agree the kill criteria before the pilot starts, and keep this off any roadmap that also assumes framework-level replacement.
How can I help you explore Laravel packages today?