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

Craftable Laravel Package

brackets/craftable

Craftable is a Laravel admin panel and CRUD generator for building customizable backends quickly. It includes authentication, roles and permissions, media management, and ready-made UI components to speed up admin development.

View on GitHub
Deep Wiki
Context7

Getting Started

Craftable is not a drop-in library you use in an existing app — it is an administration scaffold. The intended entry point is a fresh Laravel 8 application (or the brackets/craftable-project skeleton), because installation publishes auth, layouts, routes, and a Vue/Inertia front end that you are expected to own and edit.

Minimal steps:

composer require brackets/craftable
php artisan craftable:install      # publishes config, assets, migrations, seeds admin user
php artisan migrate
npm install && npm run dev         # or watch
php artisan serve

Log in at /admin with the seeded credentials (check the installer output — it prints them). The three places to look first:

  1. routes/admin.php — every admin route, including generated CRUD routes, is registered here.
  2. resources/js/admin/ — Inertia pages and Vue form/table components; this is where the UI actually lives.
  3. app/Http/Controllers/Admin/ — generated controllers extending Craftable's base CRUD controller.

The first real use case is generating an entity:

php artisan admin:generate

Walk the interactive prompts (model name, fields and their types, whether the entity is translatable, whether it has media). The generator emits a migration, model, form request, admin controller, Vue index/create/edit pages, routes, and permission records. Run php artisan migrate, assign the new permissions to a role in the built-in Roles & Permissions screen, and the CRUD is live.

Implementation Patterns

Generator-first, then hand-edit. Treat admin:generate as a scaffolding event, not an ongoing source of truth. Commit the generated files, then customize freely. Regenerating the same entity will overwrite your edits, so most teams only re-run it for brand-new entities.

Controller pattern. Generated controllers extend the package's base CRUD controller and declare an $indexView, $createView, $editView, and a model class. Index actions receive sorting and search query parameters from the Vue table, so custom filters are added by extending the query in the controller and passing filter options back as Inertia props.

Vue page pattern. Each generated entity has an index page (table, search, sort, bulk delete, pagination) and a form page composed of field components (text, textarea, richtext, select, checkbox, date, media, etc.). To change behavior, edit the Vue page or the field component in resources/js/admin — not the PHP side. Form submissions go through Inertia to the controller's store/update.

Translatable content. If the entity is flagged translatable, the generator uses a translation table or JSON column plus a locale switcher. Forms render one tab per configured locale. Non-translatable fields sit outside the tabs, and validation rules must be keyed by locale in the form request.

Media and files. Craftable leans on Spatie MediaLibrary. Models must implement HasMedia and register collections; the media field component expects that collection name. Thumbnails/conversions are configured in the model's registerMediaCollections/registerMediaConversions, not in the admin UI.

Permissions and menu. Every generated entity registers index/create/update/delete abilities. Roles and permissions are managed inside the admin itself; the menu is config-driven (order, icon, permission gate), so hiding a section for non-admins is a config change plus a permission assignment. Super-admin bypasses checks.

Integration tips. Publish config and views (vendor:publish --provider=...) before overriding, so your customizations survive a composer update. For bespoke admin screens that the generator can't express, build a normal Laravel controller + Inertia page in the same namespace and register the route in routes/admin.php so it inherits auth and layout.

Gotchas and Tips

  • Laravel 8 lock-in is real. The last release was October 2023 and the package targets Laravel 8. Don't expect a smooth upgrade to Laravel 10/11; pin laravel/framework and related packages, and plan to fork or migrate rather than composer update blindly.
  • It is scaffolding, not an upgradable dependency. Merging upstream changes after you've edited generated controllers and Vue pages is effectively a manual diff. Decide early that the app owns this code.
  • Migrations are not run for you on generation. A generated entity's table won't exist until you php artisan migrate; the resulting 500 is a common first-run confusion.
  • Permissions are the usual cause of 403s. A fresh entity is invisible to non-super-admins until its abilities are attached to a role. If the menu item is missing, check the menu permission gate before suspecting the route.
  • Blank admin pages are almost always asset or cache issues. Run npm run dev (or build), clear config:cache and route:cache, and check for a stale Inertia manifest. After adding routes, re-run route:clear.
  • Uploads failing silently usually means the media collection isn't registered on the model, or the field name in the Vue form doesn't match the collection/attribute expected by the controller.
  • Distinguish 419 vs 403 vs 500 when debugging. 419 is CSRF/session (often a stale Inertia page after a redeploy), 403 is permission, 500 is usually a missing migration column or an unregistered relation. Vue Devtools plus the Inertia network payload shows exactly which props the controller sent.
  • Query parameter names are a contract. Sorting and filtering rely on the parameter names the Vue table emits; renaming them in the controller without updating the page breaks behaviour invisibly (no error, just no sorting).
  • Extension points to know: the base CRUD controller (subclass it for custom index queries), published config (menu, locales, pagination), and the field component registry in resources/js/admin for adding a custom input type.
  • Don't use it for the public site. It's an admin toolkit; the frontend Inertia pages are incidental. Keep your public routes in routes/web.php and leave routes/admin.php for the panel.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect