flipbox/lumen-generator
Brings Laravel's artisan generator commands to Lumen. Adds make:model, make:controller, make:middleware, make:command and more, along with other missing Laravel features, so you can scaffold Lumen apps with the familiar Laravel workflow you already know.
Install the package and register its service provider in bootstrap/app.php — it is not auto-discovered in Lumen like a Laravel package would be:
composer require flipbox/lumen-generator
// bootstrap/app.php
$app->register(Flipbox\LumenGenerator\LumenGeneratorServiceProvider::class);
Place the registration after $app->withFacades() and $app->withEloquent() (if you use them) but before route file loading, so commands like route:list can resolve the router state.
Look first at php artisan list — that is the whole point of the package: converting Lumen's tiny Artisan surface into the full Laravel generator toolkit. The first concrete use case is scaffolding a resource the normal way:
php artisan make:model Post -mf
php artisan make:controller PostController --resource
php artisan route:list
From there, treat make:* and the auditing commands (route:list, storage:link, key:generate, vendor:publish) as your everyday workflow.
Scaffolding a resource slice end-to-end. Combine generator flags to avoid running five commands:
php artisan make:model Post -mf # model + migration + factory
php artisan make:controller PostController --resource
php artisan make:request StorePostRequest
php artisan make:resource PostResource
Then register the routes manually in routes/web.php (Lumen has no Route::resource auto-discovery issues, but you must still call $router->group() yourself).
Command-driven DDD-ish structure. Use make:job, make:event, make:listener, make:mail, make:notification, make:policy, make:observer, make:rule, make:exception, and make:test to keep a consistent App\ namespace tree. Lumen's default namespace is App\, so generated classes drop in cleanly as long as you never renamed the root namespace in composer.json.
CI and pre-commit auditing. A useful pipeline step is php artisan route:list --json (or plain output) to catch duplicate or missing route registrations after refactors — this is something stock Lumen cannot do at all, and it's the highest-leverage daily command in the package.
Container/deploy hooks. Run php artisan storage:link as part of your container entrypoint or post-deploy script so public/storage exists before the app serves uploads. Similarly, php artisan key:generate is the canonical way to populate APP_KEY on a fresh Lumen install (Lumen does not generate it for you).
Extending a generated class. When the stub isn't what you want, subclass the relevant command (e.g., extend the package's model command) and override getStub() / replaceClass(), then register your version in bootstrap/app.php with $app->singleton(...) / a small custom ArtisanServiceProvider. That's the cleanest extension point — the package does not ship a stub:publish equivalent you can rely on across versions.
Combining with vendor:publish. Third-party Lumen packages that expose config or migrations will only publish correctly if they registered their assets via publishes() — the package's vendor:publish command enables that, but the target package has to cooperate.
make:controller emits classes extending App\Http\Controllers\Controller, but Lumen does not ship that class. Create app/Http/Controllers/Controller.php once (a plain abstract extending nothing, or Illuminate\Routing\Controller) before your first controller command, or the generated files will fatal on load.make:command does not register the command. Lumen has no app/Console/Kernel.php by default. You must add the command to $app->singleton() / the console kernel (or a custom service provider) yourself. Autoloading is not automatic like in Laravel.database/seeds → database/seeders. If your Lumen bootstrap points at the old path, a generated DatabaseSeeder can land in a directory db:seed never looks at. Check database/ layout after the first make:seeder and adjust either the path or your seeding config.make:model -f needs Faker. Factories rely on fakerphp/faker; install it as a dev dependency or the factory command (and later db:seed with factories) will fail on class-not-found.withEloquent() must be on. Model/migration commands generate files regardless, but any command that needs to resolve models (make:factory inspecting a model, route:list with eloquent-bound routes, db:seed with model factories) will behave unpredictably if $app->withEloquent() is commented out in bootstrap/app.php.route:list and route ordering. Register the service provider before your route files. If you see an empty or partial list, the app booted the console kernel before routes were loaded — move the register() call or inspect whether routes are loaded lazily via $router.key:generate writes to .env, not to config/. Lumen reads APP_KEY from env and the cipher from config/app.php; if you've hardcoded the key elsewhere, key:generate will silently write a value that has no effect. Verify 'key' => env('APP_KEY') and 'cipher' => 'AES-256-CBC'.storage:link and APP_URL/public path. If APP_URL is wrong or you've customized the public directory, the symlink target is wrong. Confirm with ls -la public/ after running.config:cache, route:cache, view:cache, optimize, and event:cache are intentionally absent because Lumen doesn't support them. Don't plan a deploy around them — check php artisan list for the actual surface.illuminate/* components). If you get "Class not found" errors from Illuminate\Foundation\Console\*, your illuminate/foundation version is out of sync — resolve by aligning lumen/framework and the package version together, or explicitly require the matching illuminate/* sub-packages.App\. If you've customized the autoload root namespace, make:* output will need manual editing on every command — either revert the namespace change or subclass the generators to override getNamespace().-vvv; most failures are stub-path resolution issues in GeneratorCommand (the file exists in the package but not in your vendor tree) or missing destination directories. Creating the target directory once usually resolves it.How can I help you explore Laravel packages today?