saritasa/laravel-repositories
Saritasa's Laravel Repositories package provides a structured repository layer for Eloquent models, including base repository classes, reusable query criteria, and helper abstractions that keep controllers and models lean while centralizing data access, filtering, and persistence logic.
composer require saritasa/laravel-repositories — read the released version first. 4.0.0 explicitly declares Laravel 11 compatibility, so it is the version to target on Laravel 11. On Laravel 12+ there is still no declared support; verify resolution or copy src/ into app/Repositories/ and treat it as vendored code.BaseRepository. Open it and the repository contract side by side — this is a thin wrapper over Eloquent, so its whole value is the handful of CRUD/query helpers it provides. Don't expect criteria, presenters, or caching layers.final class UserRepository extends BaseRepository implements UserRepositoryInterface
{
protected $model = User::class; // set explicitly; don't rely on name inference
}
// AppServiceProvider::register()
$this->app->bind(UserRepositoryInterface::class, UserRepository::class);
// Controller / Action
public function show(UserRepositoryInterface $users, int $id): UserResource
{
return new UserResource($users->find($id));
}
That's the whole happy path: interface → implementation → injected into a controller or action.
UserRepositoryInterface) for every concrete repo, and inject the interface — not the class — into controllers, actions, jobs, and listeners. This keeps tests mockable and lets you swap implementations later.BaseRepository as your baseline CRUD surface (find, all, create, update, delete, pagination). Add domain methods (findActiveByEmail, paginateRecentForTeam) rather than exposing a generic query builder to callers.with()/query helpers to preload relationships in read methods so controllers and resources never trigger N+1. Make the eager-load list a parameter or a per-method default.DB::transaction(). Don't grow the repo into an orchestrator.where/orderBy/scope-style helpers, chain them inside named repo methods and keep the call sites declarative.composer.json constraint bump: expect zero source diffs, but expect your illuminate/* range to shift. If you're still on Laravel 10, read the 4.0.0 constraint before upgrading — a major bump can drop the older framework from the allowed range and stall composer update entirely.composer.json ("saritasa/laravel-repositories": "4.0.0" or ^4.0), and fork/copy the base class into app/Repositories/AbstractRepository the moment the dependency causes upgrade friction.src/. Budget for that.AdminUserRepository → User) can silently resolve wrong. Always set $model explicitly.prettus/l5-repository, you get no request-criteria, no presenters, no transformers. Build those yourself or pick a maintained alternative if you need them.getModel()/newQuery() (or equivalent) and the CRUD methods. Overriding newQuery() is the cleanest place to inject default ordering/scopes — but scope it deliberately, or every query inherits it.all()/find() don't preload, watch for N+1 in list endpoints. Be explicit with with().create() vs save() semantics. Mass-assignment via create() respects $fillable/$guarded; direct save() on a hydrated model does not. Mixing the two in one repo is a common source of "why did this field save?" bugs.How can I help you explore Laravel packages today?