rogervila/laravel-legacy-ui
rogervila/laravel-legacy-ui restores Laravel's classic Bootstrap-based UI and auth scaffolding on newer versions, letting you keep familiar login, registration, and password-reset views without rewriting legacy templates. Simple Artisan commands publish the views.
This is essentially a maintained fork of laravel/ui that keeps the classic ui + auth scaffolding commands working on Laravel 8 and 9. Treat it as "Breeze/Jetstream's older sibling": session-based auth, Blade layouts, and a frontend preset (Bootstrap, Vue, or React) driven by Laravel Mix.
Minimum steps to a working login:
composer require rogervila/laravel-legacy-ui
# Choose one preset; --auth also scaffolds login/register/password-reset
php artisan ui bootstrap --auth
# or: php artisan ui vue --auth
# or: php artisan ui react --auth
npm install && npm run dev
php artisan migrate
Then visit /login and /register. Configure MAIL_* in .env before testing password reset.
Where to look first
vendor/rogervila/laravel-legacy-ui/src/ — the command classes and their stubs. Every file that gets published lives here, so this is your source of truth for "what will this change in my app?"composer.json of the package — the illuminate/* constraints tell you the exact Laravel versions supported (8 and 9 only).resources/views/auth/, resources/views/layouts/, app/Http/Controllers/Auth/, and the routes appended to routes/web.php.First use case: bootstrapping a fresh Laravel 8/9 app with classic email/password auth when you don't want the Tailwind/Inertia assumptions of Breeze or the team features of Jetstream. It is also useful when upgrading an older (Laravel 5/6/7 era) app and you want familiar auth scaffolding rather than relearning a new starter kit.
The canonical fresh-app flow
laravel new myapp
cd myapp
composer require rogervila/laravel-legacy-ui
php artisan ui bootstrap --auth
npm install && npm run dev
php artisan migrate
Add MustVerifyEmail to App\Models\User and apply the verified middleware if you want email verification — it is not wired up by the scaffolding.
Pick the preset by what you actually need
bootstrap --auth — plain Blade + Bootstrap. Best default for server-rendered CRUD apps; no JS build complexity beyond Mix.vue --auth / react --auth — adds the JS preset plus an ExampleComponent, mounts it, and includes an auth-layout scaffold. Use only if you're genuinely building a JS-driven frontend; otherwise you inherit a build toolchain you don't use.php artisan auth (without ui) — just the auth controllers, views, and routes, no frontend preset. Useful when you already have a CSS framework in place.Post-scaffold customization
Everything the commands generate is published into your app, so normal Laravel patterns apply:
resources/views/layouts/app.blade.php with your own shell.app/Http/Controllers/Auth/* directly — validation rules, redirect targets (RouteServiceProvider::HOME), throttling.users migration together.Integration with existing apps
Run the scaffolding once on a branch. The commands append auth routes to routes/web.php and copy files into existing directories. Review git diff before committing: check for overwritten web.php, ExampleComponent.vue, app.js, and any layout collisions.
Composing with your own auth logic
Because the controllers are yours after publishing, this package plays well with custom flows — e.g., add a role column, gate registration behind an invite token, or add 2FA in the LoginController. There is no package runtime to fight; it's scaffolding, not a framework.
Do not install alongside laravel/ui. Both auto-register a service provider and ship commands named ui and auth. Composer will not stop you, but Artisan will resolve one command arbitrarily and you'll get confusing "no such option" errors. Remove laravel/ui first.
This is Laravel Mix, not Vite. On Laravel 9 you get webpack.mix.js and package.json scripts running mix, even though the base app expects Vite. If your app already has a vite.config.js, you'll be maintaining two build pipelines. Options: keep Mix just for these assets, or port the CSS/JS imports to Vite manually after publishing.
Node dependencies are dated. Expect laravel-mix, older bootstrap, and legacy vue-loader/sass-loader versions. npm install will likely print deprecation warnings and npm audit will flag things. Pin working versions in package.json and commit package-lock.json; do not assume a fresh install resolves cleanly against current Node LTS.
Re-running commands is destructive. The scaffold copies stubs over existing files. Back up or commit before re-running php artisan ui ..., and never run it twice just to "refresh" — you'll get duplicated route definitions and duplicate named routes (login, register), which breaks route() calls and route:list.
Check the Bootstrap major the stubs emit. Different laravel/ui-lineage releases target Bootstrap 4 vs 5; the markup (data-bs-* vs data-toggle) differs. Inspect a generated view before writing custom CSS against a class that isn't there.
Version lock. Last release February 2022, supporting only Laravel 8 and 9. It will not install on Laravel 10+. If you plan to upgrade, budget time to migrate off this package (to Breeze, or hand-rolled auth) rather than expecting a new tag.
Debugging checklist
php artisan route:list --path=login — confirm routes registered exactly once and point at the published controllers.route('login') is undefined, the auth routes were never appended — re-check routes/web.php and that the command completed.npm run dev or @vite is in your layout while assets are compiled by Mix (or vice versa).MAIL_MAILER and the password-reset table migration ran.Extension points. Fork the stubs in vendor/rogervila/laravel-legacy-ui/src (or copy them into your app's own scaffolding command) if you need repeatable house-style auth across projects. Since everything is published plain PHP/Blade, the practical "extension point" is simply editing the generated files — that is the intended workflow, not a limitation.
How can I help you explore Laravel packages today?