Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Crud Forms Laravel Package

atcliff/laravel-crud-forms

A Laravel package for scaffolding CRUD forms with minimal boilerplate. Define fields and validation once, then render create, edit, and delete interfaces via Blade components, ready to drop into any Eloquent resource.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Confirm the package is installable before you build on it. There's no tagged release since December 2019 and zero dependents, so treat the install as a spike, not a commitment:

composer require atcliff/laravel-crud-forms --dev
composer show atcliff/laravel-crud-forms   # inspect version, requires, autoload

If Composer resolves against a dev-master branch, pin the exact commit in composer.json ("atcliff/laravel-crud-forms": "dev-master#<sha>") so a force-push upstream can't silently change your code. If it hard-requires Laravel 5.x/6.x and you're on 10/11, stop here and fork it — don't fight the constraint with --ignore-platform-reqs in a real app.

2. Find the service provider and publish assets. Open vendor/atcliff/laravel-crud-forms/composer.json → extra.laravel.providers (or check for package discovery). Then:

php artisan vendor:publish --provider="AtCliff\CrudForms\CrudFormsServiceProvider"
php artisan list | grep -i crud     # look for generator/install commands

Read the published config/crud-forms.php first — that's where field-type→Blade-partial mappings, route prefix/middleware, and layout/view paths will live, and it tells you more about the package's design than the README does.

3. Read three files before writing any code: the base controller (or trait) the package expects you to extend, the field-rendering Blade partials, and the generator command if one exists. Those define the contract you're coding against.

4. First use case — scaffold one trivial resource end to end. Pick a Post (title:string, body:text, published_at:datetime, status:enum) and get /posts/create rendering and storing. Do it by hand first (controller + form definition + one Blade view) rather than via the generator, so you understand what the generator produces. Only then run the generator on a second model and diff the output against your manual version.

Implementation Patterns

Declarative form definitions per model. The package's core idea is a field map that drives both create and edit rendering plus validation. Keep it in a dedicated class or config file, not inline in the controller:

// app/Forms/PostForm.php
return [
    'title'        => ['type' => 'text',     'label' => 'Title',  'rules' => 'required|max:255'],
    'body'         => ['type' => 'textarea', 'label' => 'Body',   'rules' => 'required'],
    'status'       => ['type' => 'select',   'options' => Post::STATUSES, 'rules' => 'required|in:...'],
    'published_at' => ['type' => 'datetime', 'rules' => 'nullable|date'],
];

The win is that store and update share one definition — the day-to-day value is not retyping validation rules in two FormRequests.

Thin controller + resource routes. Extend the package's base controller and set the model/form as properties; register Route::resource('posts', PostController::class) inside your auth/admin middleware group. The package almost certainly does not ship authorization, so gate the whole group — don't rely on it to check policies per action.

Custom field types via partials. For belongsTo, belongsToMany, file uploads, or WYSIWYG, publish the views and add a partial, then register the type in config:

'fields' => ['author_id' => ['type' => 'belongsTo', 'model' => User::class, ...]]

belongsToMany (multi-select + sync) and polymorphic relations are usually the first things a generic CRUD package gets wrong — expect to write those by hand in the controller's store/update after the base save.

Wrap the views in your layout. Set the layout/view-path config to your app layout and let the generated views be @section/@yield content. Publish views once (--tag=views) and commit them — treat them as your code from that point, not vendor code.

Override per-model when needed. For one-off fields, drop a model-specific partial (resources/views/vendor/crud-forms/fields/post-seo.blade.php) rather than forking the whole package view tree.

Feature-test the two write paths immediately. $this->post(route('posts.store'), $payload)->assertRedirect() and the update equivalent, including an invalid-payload case. Since the package is unmaintained, these tests are your regression net for when you eventually replace it.

Gotchas and Tips

  • It's abandoned in all but name. Last release 2019, 0 stars, 0 dependents. Assume no fixes. Fork it into app/ or a private VCS repo if you plan to use it past a prototype. Do not make it a load-bearing dependency in a client project without a replacement plan.
  • Laravel-version drift is the likely failure mode. 2019-era code hits removed helpers (str_slug, array_get), $dates vs $casts, Blade @php changes, and the Laravel 9+ Symfony response changes. Run the full test suite on the target framework before anything else.
  • Mass assignment / request handling. Check whether the base controller uses $request->all() or $request->validated(). If it's the former, you must set $fillable correctly on every model — a stray is_admin field in a form config becomes a privilege escalation.
  • Validation lives in a config array, not a FormRequest. That means no per-action rules (e.g. unique-on-update ignoring the current ID) unless the package supports placeholders. Verify Rule::unique(...)->ignore($post) is expressible; if not, override rules() in the controller.
  • File uploads: confirm the generated <form> includes enctype="multipart/form-data" and that the disk is configurable. Run php artisan storage:link. Test with a real upload, not just text fields.
  • Config caching. After editing config/crud-forms.php, run php artisan config:clear — a stale cached config is the #1 "my field type isn't registering" cause.
  • Route model binding + soft deletes. destroy on a soft-deleting model should delete() not forceDelete(); check the base controller and override if needed.
  • Debugging checklist: php artisan route:list --path=posts, dd(config('crud-forms')), dd($formDefinition) in the controller, and check the rendered HTML for missing CSRF/@error blocks.
  • Extension points to prefer (least fragile to most): config field types → per-model published partials → subclassing the base controller → forking the package. Anything past step 3 means you've effectively adopted it.
  • Know when to walk away. If the spike takes more than a day, reach for Filament, Backpack, or hand-rolled Blade components + FormRequests instead. A 2019 single-author CRUD generator with no users is a liability, not a head start; the honest assessment is that its value here is as a pattern reference, not a runtime dependency.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums