A new application
innoboxrr/laravel-setup turns a fresh Laravel 13 application into the ecosystem's base app:
- A public site editable from the admin panel: home, join, contact, privacy notice and terms, with a complete sample site.
- Authentication through
innoboxrr/laravel-auth: registration, login, password reset, email verification and impersonation for administrators. - An admin panel whose menu builds itself, with notifications, a profile with avatar and password, a site editor, and links to the logs and the
.enveditor. - Users generated by LaraPack, with the same architecture as any model you add later.
Installation is split in two on purpose: app:setup writes the files and app:install installs. In between you can review exactly what changed with git diff.
Before you start, check the requirements.
1. Create the Laravel application
laravel new my-app
cd my-appOr with Composer:
composer create-project laravel/laravel my-app
cd my-appConfigure the database in .env. If the installer didn't create a repository, create one now so step 5 shows exactly what changed:
git init
git add -A
git commit -m "Fresh Laravel"2. Set APP_URL
Put the address you will open the app with in .env, port included:
# with composer run dev or php artisan serve
APP_URL=http://127.0.0.1:8000
# with a Laragon host
APP_URL=http://my-app.testWhy it matters
The admin panel calls the API with the session cookie, and Sanctum only accepts it from the domains in SANCTUM_STATEFUL_DOMAINS: by default localhost, 127.0.0.1:8000 and the APP_URL host, among others. From any other address, login succeeds but every admin table answers 401 and sends you back to login. See Requirements.
3. Install laravel-setup
composer require --dev innoboxrr/laravel-setup4. Configure with app:setup
php artisan app:setupphp artisan app:setup --reactapp:setup only runs on an application that looks fresh: resources/views/welcome.blade.php must exist, and laraimport.json, resources/vue/app and resources/react/app must not. Otherwise it refuses. --force overrides this, but think about what it replaces first.
It installs nothing. It does seven things:
| Step | What it does |
|---|---|
| Composer dependencies | Writes the ecosystem packages to composer.json, with LaraPack in require-dev. Removes lab404/laravel-impersonate, which laravel-auth replaces. |
| Environment | Writes the keys in the table below to .env and .env.example. |
| Administrators | Adds admins to config/auth.php, read from ADMIN_EMAILS. |
| Backend | Copies bootstrap/app.php, bootstrap/providers.php, routes/web.php, AppServiceProvider, the admin middleware, the .env editor config, a migration adding payload and soft deletes to users, SiteOptionsSeeder and laraimport.json. |
| Interface | Copies package.json, vite.config.js, resources/views/app.blade.php, resources/<ui>/app/** and a placeholder resources/<ui>/routes.json. |
| Routes for the frontend | Writes config/routes-to-json.php so route:json exports to resources/<ui>/routes.json. |
| Users, with LaraPack | Deletes app/Models/User.php, generates the user from laraimport.json with larapack:import, creates the RouteServiceProvider and EventServiceProvider, and copies a UserPolicy that lets each user view and edit their own account. |
If LaraPack rejects anything, app:setup fails and prints LaraPack's output.
What it replaces and what it deletes
- Replaces
bootstrap/app.php,bootstrap/providers.php,routes/web.php,app/Providers/AppServiceProvider.phpandpackage.json. - Deletes
resources/views/welcome.blade.php,resources/js,resources/cssandapp/Models/User.php.
That's why it only runs on a new application.
Environment variables it writes
These are always written, even if they already had a value:
| Key | Value |
|---|---|
APP_LOCALE | es |
APP_FALLBACK_LOCALE | en |
APP_FAKER_LOCALE | es_MX |
SESSION_DRIVER | database |
The interface ships in Spanish because of APP_LOCALE=es. Change it to en if you want English.
These are only added when missing:
| Key | Value | Purpose |
|---|---|---|
ADMIN_EMAILS | empty | Who administers the app. |
LARAVEL_UPLOADS_DISK | public | Where uploads such as the avatar are stored. |
LARAVEL_OPTIONS_EXPORT_DISK | local | laravel-options exports. |
LARAVEL_AUDIT_EXPORT_DISK | local | laravel-audit exports. |
VITE_APP_NAME | ${APP_NAME} | |
VITE_GOOGLE_LOGIN, VITE_FACEBOOK_LOGIN, VITE_MICROSOFT_LOGIN | false | No interface reads them yet: see Common problems. |
5. Review and name the administrator
git status
git diffThen put your email in ADMIN_EMAILS in .env. It takes several, comma-separated, and is case-insensitive:
ADMIN_EMAILS=you@example.com,someone@example.comThis is what isAdmin() on the generated user answers: policies let that user through, the admin middleware lets them in, and they can impersonate other users.
6. Install with app:install
php artisan app:installEach step runs in its own process, because the providers of freshly installed packages only exist for an artisan that boots again. In this order:
composer update --no-interaction. It isupdate, notinstall: it changescomposer.lock.php artisan vendor:publish --tag=sanctum-migrationsphp artisan notifications:installphp artisan migrate --forcephp artisan db:seed --class=Database\Seeders\SiteOptionsSeeder --forcephp artisan storage:linkphp artisan route:jsonnpm installnpm run build
If a step fails, it stops and tells you which one.
| Option | What it does |
|---|---|
--pretend | Prints the steps without running them. |
--without-build | Skips npm install and npm run build. |
--composer=composer | The Composer executable. A .phar is run with the same PHP as artisan. |
--npm=npm | The npm executable. |
On Windows, if the composer on your PATH runs an old PHP:
php artisan app:install --composer=C:/path/to/composer.phar7. Start it
composer run devThis is Laravel's own development script: it starts the server on http://127.0.0.1:8000 and Vite, among other processes. If Laragon serves the app, npm run dev is enough, or the npm run build that app:install already ran.
8. Log in as administrator
- Open
/auth/registerand sign up with an email listed inADMIN_EMAILS. The password needs at least 8 characters. - Go to
/admin.
You will see:
- Home, with one card per menu entry.
- The Administration group, for administrators only: Users, Site (the public site editor), Logs (
/log-viewer) and Environment (/env-editor), the last two in a new tab. - The notification bell, dark mode, and the user menu with your profile.
With APP_LOCALE=es, those labels appear in Spanish.
The public site lives at /, with the sample content from SiteOptionsSeeder.
All at once: app:init
If you don't need to review between steps, app:init runs app:setup and app:install back to back:
php artisan app:initphp artisan app:init --react| Argument or option | What it does |
|---|---|
domain (optional) | When done, runs configure:domain with that domain. Read the warning below. |
--react | React interface. |
--force | Configure even if the app doesn't look fresh. |
--without-build | Don't install or build the interface. |
Set ADMIN_EMAILS first
app:setup only adds ADMIN_EMAILS when it's missing. If you already wrote it in .env before app:init, it's kept, and you can register as administrator as soon as it finishes.
The domain argument only works with Laragon, with caveats
configure:domain is meant for Windows with Laragon installed at C:\laragon, a path written into the code. It adds the domain to the hosts file, asking for administrator rights, and writes an Nginx config that only accepts connections from 127.0.0.1 and allows outdated TLS protocols. It sets APP_URL to https://<domain> and SESSION_DOMAIN to .<domain>, and it does not restart Nginx: it only reminds you to.
If Laragon lives on another drive, or you don't use Laragon, create the domain with your own tooling and set APP_URL by hand.
What ends up in the application
| Where | What | Owner |
|---|---|---|
resources/<ui>/app/ | Site, auth, admin panel, state and frontend routes | Yours once installed |
resources/<ui>/index.js, resources/<ui>/src/ | The generated modules | LaraPack's: regenerated |
laraimport.json | The user declaration and whatever you add | Yours |
database/seeders/SiteOptionsSeeder.php | The sample site | Yours |
app/Http/Middleware/EnsureUserIsAdmin.php | The admin middleware | Yours |
config/auth.php → admins | Who administers, from ADMIN_EMAILS | Yours |
.larapack/manifest.json | What LaraPack generated, with hashes | Commit it |
Vue or React
Both interfaces are the same application: same routes, same screens, same site JSON, same backend calls. What differs is where things live:
| Vue | React | |
|---|---|---|
| Entry point | resources/vue/app/main.js | resources/react/app/main.jsx |
resources/<ui>/app/config.js | Only adminOnly, with route names | adminOnly with route ids, plus adminBase, adminTools, notificationsInterval, sitePages and userUpdateRoute |
| State | Pinia | Zustand |
For a generated module, a route's name (Vue) and id (React) are the same string, for example AdminUsers. More in With Vue and With React.
Common problems
Every admin table answers 401 and bounces to login. APP_URL doesn't match the address you browse, by host or by port. If you set SANCTUM_STATEFUL_DOMAINS, check it too.
"You signed in, but the session was not kept. Check the session and Sanctum domains." Login succeeded and the cookie never arrived. It is almost always SESSION_DOMAIN or SANCTUM_STATEFUL_DOMAINS.
Two applications log each other out. They share cookies on 127.0.0.1 even on different ports. Open one on localhost.
I don't see the Administration group. Your email isn't in ADMIN_EMAILS, or the config is cached: php artisan config:clear.
Model names show up untranslated. By design: LaraPack can't know what your model is called in Spanish, so it leaves the translation empty in resources/<ui>/src/locales/es.json and the English key shows. Translate it there or in resources/<ui>/app/lang/es.json.
There are no Google, Facebook or Microsoft buttons. app:setup writes VITE_GOOGLE_LOGIN, VITE_FACEBOOK_LOGIN and VITE_MICROSOFT_LOGIN, but neither interface reads them: social login is not wired into the base app. The backend does support it in laravel-auth.
Some packages are installed with no screen. innoboxrr/laravel-audit, innoboxrr/aws-file-manager, algolia/scout-extended and google/recaptcha are installed, but the base app has no interface or configuration for them.
The .env editor is enabled
The base app enables /env-editor for administrators (ENV_EDITOR_ENABLED, default true). From there you can read and change .env, secrets included. If you don't want it in production:
ENV_EDITOR_ENABLED=falseMore cases in Troubleshooting.
Next step
Your first model: declare a model, generate it and watch it appear in the menu.