amranidev/scaffold-interface
Scaffold Interface is a Laravel package that speeds up CRUD development by generating migrations, models, controllers, views, and routes from a web-based interface, helping you build admin panels and data management screens faster.
Prerequisites. This package targets Laravel 5.4–5.5-era projects (PHP 7.0–7.2) and relies on doctrine/dbal for schema introspection. Check your composer.json constraints before attempting an install on anything newer — on Laravel 6+ or PHP 8 you will almost certainly need to patch the package or run composer require --ignore-platform-reqs and fix fallout manually.
Install and register.
composer require amranidev/scaffold-interface
If package discovery doesn't pick it up (likely on 5.4, optional on 5.5), add the provider and alias to config/app.php:
Amranidev\ScaffoldInterface\ScaffoldInterfaceServiceProvider::class,
'aliases' => [
// ...
'ScaffoldInterface' => Amranidev\ScaffoldInterface\Facades\ScaffoldInterface::class,
],
Publish and migrate.
php artisan vendor:publish --provider="Amranidev\ScaffoldInterface\ScaffoldInterfaceServiceProvider"
php artisan migrate
First use case. Open http://your-app.test/scaffold. The web UI is the primary entry point: it lists your existing tables, lets you pick one (or define a new table field-by-field), and then generates a Model, a resource Controller, Blade views (index/create/edit/show), and a route registration. The fastest proof of value is scaffolding a simple table you already have — e.g. a posts table — and then diffing the output before deciding whether to keep it.
Where to look first:
/scaffold — the generation and rollback control panel.routes/web.php (or app/Http/routes.php on older versions) — where the generated routes land.app/ and resources/views/ — the generated model, controller, and Blade files.config/scaffold.php — route prefix, middleware, and generator options.vendor/amranidev/scaffold-interface/src/ — the stubs you'll want to override.Schema-first generation. Write the migration yourself, run php artisan migrate, then scaffold the resulting table. This keeps migrations as the source of truth and guarantees the generated $fillable, casts, and form fields match the real schema. It is the most reliable pattern in practice.
UI-first for throwaway prototypes. Define the table in the UI, generate, then copy the resulting migration into your own database/migrations directory immediately. The UI-created migration lives in package territory and is easy to lose track of.
Generate in dependency order. Parents before children. Define foreign keys in migrations before scaffolding so the generator can infer belongsTo relationships and render select boxes. Re-scaffolding a child after changing a parent's columns is normal.
Scaffold-as-boilerplate, then refactor. Treat the output as a first draft, not architecture. The generated controller is a working CRUD skeleton with minimal validation. Within the same branch, extract FormRequest classes, add Policy authorization, and replace inline queries with scopes or repositories. Committing generated code unreviewed is how these projects rot.
Rollback/regenerate loop. Use the UI's delete action to remove a scaffold rather than deleting files by hand — the package tracks what it generated, and mixing manual deletes with the tracker leaves orphans. Run git status before and after each generation pass so you can see exactly what appeared.
Template customization. Publish the package's stubs and edit them to match your house style — Blade layout, CSS framework (the defaults are Bootstrap-era), base controller, namespace conventions. Keep your customized stubs in version control. This is the main lever for making the output useful beyond a demo.
Programmatic generation. The facade exposes generation calls, so you can wrap scaffolding in your own Artisan command. This is useful for bootstrapping a set of admin tables in CI or in a repeatable setup script for new environments.
// pseudo-usage — verify method names against your installed version
ScaffoldInterface::generate('posts');
Auth and middleware integration. Wrap the generated routes in your auth middleware group, and add authorize() calls inside each generated method. Generated routes are registered as Route::resource, so you can also replace them with explicit route definitions once the controller is stable.
It is effectively abandoned. Last release was November 2017. Framework helper removals (str_*, array_*), the boot() signature change, and container binding changes all break it on modern Laravel. Use it on legacy 5.x admin panels or as a reference implementation — not for greenfield work.
Duplicate provider registration. On Laravel 5.5+ with auto-discovery enabled, manually adding the provider to config/app.php can cause routes to register twice, producing "route already defined" behavior. Check php artisan route:list if you see duplicates.
Route file confusion. Older versions append to app/Http/routes.php; newer versions target routes/web.php. If your routes don't appear, grep both files.
Generation overwrites. Files with matching names are overwritten silently. Commit or stash before generating, and never generate on top of hand-edited controllers without a backup.
doctrine/dbal version pinning. Newer 3.x releases aren't compatible with the package's schema calls. Pin to ^2.x explicitly:
composer require doctrine/dbal:^2.0
Clear caches after every generation. Route and view caches will hold stale state and produce 404s or missing-class errors:
php artisan route:clear
php artisan view:clear
composer dump-autoload
Column type mapping is imperfect. enum, json, unsignedBigInteger, and some timestamp variants may be rendered as string/text or skipped entirely. Always review the generated migration and model casts after scaffolding a complex table.
Naming conventions matter. Tables must be plural snake_case. Singular table names produce awkward model/controller names and break relationship inference. Reserved SQL words (order, group) will generate broken code.
Foreign keys must pre-exist. The UI does not reliably infer relationships from naming alone. If a user_id column renders as a plain input instead of a select, the FK constraint wasn't present when you scaffolded.
Validation is thin, authorization is absent. Generated controllers typically validate required fields only inline and contain no policy checks. Add FormRequest validation and $this->authorize(...) before any of this reaches production.
Verify $fillable. Some versions omit foreign key columns from the generated $fillable array, causing silent mass-assignment failures. Cross-check against the migration.
Blade output is dated. Views assume Bootstrap 3/4 markup and a specific layout name. Either publish and rewrite stubs, or treat the views as reference only and rebuild them in your own component system.
Debugging a blank page. Generator exceptions often surface as a white screen because the UI swallows errors. Enable APP_DEBUG=true, tail storage/logs/laravel.log, and confirm registration with php artisan route:list | grep scaffold.
Orphaned scaffolds. The package's tracker table and the filesystem can diverge. If you delete the DB record without removing files (or vice versa), rollback stops working. Do all deletions through the UI.
How can I help you explore Laravel packages today?