Every new Laravel project I built for eight years started the same way. I opened the last project, copied the folder, and started deleting things I didn’t need this time.
The controller had the same response shape. The exception handler had the same three fallbacks. The repository had the same filter-and-sort logic wearing a different model’s name. None of this lived in a package. It lived in whichever project I’d built most recently, waiting to be copied forward, slightly mutated, into the next one.
This is not a story about laziness. Copy-paste is what disciplined engineers do when nobody has written down the rules yet. You learn a shape works, you carry it forward, and you trust your memory more than a shared source of truth — because there isn’t one.
The cost shows up later, and it shows up sideways. Two services in the same codebase return errors in different shapes because they were copied from different generations of the same idea. A junior engineer builds a new endpoint that returns a raw Eloquent model — technically correct, structurally incompatible with everything else the API promises. Nobody decided this. It just accumulated, one copy at a time, across eight years and however many client projects.
The problem was never code quality. It was the absence of a foundation to copy from.
Clean code books teach you how to write a good class. They don’t tell you what a Laravel application’s controller layer owes to its service layer, or what a service is contractually required to return, or how an exception should render itself without every controller reinventing a try-catch. Those are foundation decisions, and foundation decisions don’t fit in a style guide. They need to be executable — something you extend, not something you remember to follow.
So I stopped copying and started extracting. Every base class I’d rewritten from memory across a dozen projects became one real class, in one real package, with one real contract. BaseController, BaseService, BaseRepository, BaseApiException, BaseRequest, BaseResource — not a scaffold you eject and modify, but a layer you extend and never override in the wrong direction. A response envelope that is the same whether the endpoint was written by me this week or by someone else three years from now.
// Before — every project, a slightly different version of this
class OrderController extends Controller
{
public function store(Request $request)
{
$order = Order::create($request->all());
return response()->json($order); // shape depends on who wrote it, and when
}
}
// After — core-foundation, every project, the same contract
class OrderController extends BaseController
{
public function store(StoreOrderRequest $request)
{
$order = $this->orderService->create($request->validated());
return $this->createdResponse(
message: 'Order created successfully.',
payload: new OrderResource($order),
);
}
}
Same two lines of business logic. One of them is guessable from the outside. The other one is guaranteed.
That package is core-foundation, and after eight years of private iteration across enterprise Laravel projects, it’s now open source.
It is not a framework. Laravel is still the framework. This is the layer of decisions Laravel deliberately leaves to you — how errors render, how repositories cache, how services stay safe under Octane’s persistent workers — made once, correctly, and shared instead of re-derived per project.
Who this is for. Teams running more than one Laravel service, where consistency has to be enforced by code, not by a wiki page nobody reads. Engineering leads tired of reviewing the same “why does this endpoint return something different” comment. Laravel developers who’ve felt the specific pain of onboarding into a codebase where every module looks like a different project wearing the same routes file.
Who this is not for. A single small app with one maintainer, shipped once, rarely touched again. If there’s no second project to keep consistent with the first, you don’t need a foundation — you need to ship. Foundations pay for themselves in the second, third, and tenth project. Not the first.
Over the next few posts I’ll go layer by layer through the parts of this that took the longest to get right.
The Foundation Papers — one part a day
1. Eight Years of Copy-Paste. Then I Stopped. (this post — free architecture)
2. Your API Has No Shape. — the response envelope
3. Three Layers. No More, No Less. — the exception hierarchy
4. The Query That Corrupted Our Data. — locking and atomic updates
5. Cache That Knows When to Forget. — tag-based repository caching
6. What Breaks When Your Server Doesn't Restart. — Octane safety
7. The Incident That Made Me Charge For This. — why the tooling above is paid
8. I Can See Exactly Where My API Is Slow. Can You? — Server-Timing (Pro)
9. One Command. An Entire Module. — core:make scaffolding (Pro)
10. I Taught My AI How I Code. — AI assistant context (Pro)
11. Why Not Just Use Laravel's Defaults? — the honest objection
12. What an Inconsistent API Actually Costs You — the case for a foundation
13. Free or Pro? A Decision Framework — how to actually decide
Each one is a decision I made under production pressure, wrote down permanently, and no longer have to make again.
The base architecture — everything in this series — is open source under MIT, forever. It has to be, or none of the trust I’m asking you to place in it means anything. What isn’t free is the tooling I built on top of it to make it fast to actually use in a real team: scaffolding that generates a fully-wired module in one command, profiling that shows you exactly where a request slows down, and an AI context layer that turns a coding assistant into something that already knows this architecture instead of guessing at it. That’s the part I charge for, at https://packagist.org/packages/rupeshstha/core-foundation, because maintaining that well is ongoing work, and ongoing work doesn’t stay good for long when it’s unpaid.
composer require rupeshstha/core-foundation. MIT licensed. Repo is open — read it, extend it, argue with a decision in an issue if you disagree with one.
Start here: Welcome to Core Foundation · Installation