youbar / easy-crud
Convention-driven CRUD controllers for Laravel. Magic by default, overridable everywhere.
Package info
pkg:composer/youbar/easy-crud
Requires
- php: ^8.2
- illuminate/console: ^12.0|^13.0
- illuminate/container: ^12.0|^13.0
- illuminate/contracts: ^12.0|^13.0
- illuminate/database: ^12.0|^13.0
- illuminate/http: ^12.0|^13.0
- illuminate/routing: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
- illuminate/validation: ^12.0|^13.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.18
- orchestra/testbench: ^10.0|^11.0
- phpunit/phpunit: ^11.5|^12.5|^13.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-28 18:18:45 UTC
README
Convention-driven CRUD controllers for Laravel. Magic by default, overridable everywhere.
Most Laravel APIs contain the same controller forty times: list a model with
pagination, show one, create one, update one, delete one. easy-crud writes
that part once, without assuming your project is laid out like anyone else's.
class PostController extends CrudController { protected string $model = Post::class; }
Route::crud('posts', PostController::class);
That is a working, paginated, policy-aware JSON API.
easy-crud ships no conventions, so it assumes nothing about your namespaces: out of the box it returns plain JSON and validates nothing. Tell it where your resource and request classes live, once, and it finds them for every model from then on.
Installation
composer require youbar/easy-crud
Requires PHP 8.2+ and Laravel 12 or 13.
The idea
One config table maps a role to a pattern, and it ships empty:
'conventions' => [ 'resource' => ['App\Http\Resources\{Model}Resource'], ],
Ordered candidates, a {SubNamespace} placeholder for models grouped into
folders, a {Domain} one for modular layouts, or a closure when no pattern
fits.
A row only answers which class. The package acts on three of them —
resource, collection and request. Any other row resolves a class and waits
for you to read it in an override, which is how a service, action or repository
layer plugs in without the package knowing anything about it.
Three levels
| Conventions | Declare a model. Add a pattern per role, and every model resolves from it. |
| Method overrides | ~15 named, typed, defaulted protected methods. Override what you need. |
| Contracts | Rebind class resolution, authorization or transformation wholesale. |
Seeing what it decided
php artisan easy-crud:conventions Post
Model App\Models\Post
Resource App\Http\Resources\PostResource resolved (pattern 1 of 1) ✓
Collection — fallback: PostResource::collection()
Request
index App\Http\Requests\IndexPostRequest not found → no validation ✗
show App\Http\Requests\ShowPostRequest not found → no validation ✗
store App\Http\Requests\StorePostRequest resolved (pattern 1 of 2) ✓
update App\Http\Requests\Post\UpdateRequest resolved (pattern 2 of 2) ✓
destroy App\Http\Requests\DestroyPostRequest not found → no validation ✗
Policy App\Policies\PostPolicy view, create, update ✓
skipped viewAny, delete
Custom roles (resolved only — easy-crud has no behaviour for these)
repository App\Repositories\PostRepository resolved (pattern 1 of 1) ✓
Pagination length_aware perPage|per_page, default 15, max 100 ✓
Scaffolding
php artisan make:crud-controller PostController --all
Generates the controller plus the resource and request classes — at the exact paths your conventions look in, so what it writes is guaranteed to be found.
Documentation
The pages live in docs/content as plain Markdown and are
rendered by youbar.nl, which pulls this directory straight from git. Editing
docs needs no toolchain.
Contributing
See CONTRIBUTING.md. In short: conventional commits,
squash merges, composer test green.
License
MIT. See LICENSE.md.
