The most honest objection I get about core-foundation isn’t about the price. It’s this: Laravel already gives you controllers, requests, resources, and exceptions. Why do you need a package to tell you how to use the tools you already have?
It’s a fair question, and the honest answer is that Laravel’s defaults are deliberately unopinionated about the exact things that end up mattering most once a codebase has more than one contributor. Laravel gives you a FormRequest with a rules() method — it does not tell you that creating something and updating it should almost never share identical validation, or give you a structural reason not to bury an if ($this->isMethod('put')) inside that one method. Laravel gives you an exception handler — it does not tell you that a declined payment and a null-pointer bug should never travel through the same reporting path. Laravel gives you a resource — it does not stop you from overriding toArray() in a way that quietly diverges from every other resource in the app.
class UserRequest extends BaseRequest
{
protected function baseRules(): array
{
return ['email' => ['required', 'email']];
}
protected function updateRules(): array
{
return ['email' => ['sometimes', 'email']]; // relaxed for partial updates
}
}
baseRules() merges with storeRules() on POST and updateRules() on PUT/PATCH — later keys win. No if ($this->isMethod(...)) buried in a single rules() method, because there’s no single rules() method to bury it in.
None of this is a defect in Laravel. It’s a deliberate design choice, and it’s the correct one for a framework used across every kind of project from a weekend side app to a payment platform. Laravel can’t make these decisions for you, because the right decision genuinely differs by project. What it can’t do is make the decision consistent across your team once you’ve made it — that part has always been left to conventions, code review, and memory, and all three degrade under deadline pressure in exactly the same way.
A foundation doesn’t replace Laravel’s defaults. It’s the version of those defaults with your team’s decisions already baked in, enforced by the base class instead of a comment in a wiki nobody re-reads before writing the fifteenth controller. Hand-rolling this yourself is not wrong — I did it for eight years, project after project, before I extracted it into something reusable. The cost isn’t that hand-rolling produces bad code. It’s that hand-rolling produces the same good decisions, slightly differently, every single time you make them, and “slightly differently” compounds into “inconsistent” faster than most teams notice.
The honest test for whether you need this: open your last three Laravel projects and compare how each one handles a validation error, a 404, and a paginated response. If the answer is “the same way, because we wrote it down and everyone follows it,” you already have a foundation — it just isn’t packaged, and that’s a legitimate choice for a team small enough to enforce it by memory. If the answer is “it depends which one you look at,” that’s not a code quality problem. That’s the exact gap this package was built to close.
composer require rupeshstha/core-foundation — free, MIT. Try it against your own defaults before you decide either way. The full shared-rules pattern: Form Requests