A beautiful, reusable, and highly customizable web-based installer wizard for Laravel applications. Drop it into any project to provide a professional onboarding experience for your users — zero bloat, maximum flexibility.
storage, bootstrap/cache).php artisan make:installer-step command..env Injection — Easily prompt users for custom environment variables during the database setup step.key:generate and protects your app with API-friendly 503 middleware until installation is complete.| PHP | Laravel | Status |
|---|---|---|
| 8.2 | 10.* | ✅ Tested |
| 8.2 | 11.* | ✅ Tested |
| 8.3 | 10.* | ✅ Tested |
| 8.3 | 11.* | ✅ Tested |
| 8.3 | 12.* | ✅ Tested |
| 8.3 | 13.* | ✅ Tested |
| 8.4 | 10.* | ✅ Tested |
| 8.4 | 11.* | ✅ Tested |
| 8.4 | 12.* | ✅ Tested |
| 8.4 | 13.* | ✅ Tested |
PHP 8.2 is not compatible with Laravel 12 or 13 (those require PHP 8.3+).
Require the package via Composer:
composer require relayercore/laravel-installer
To customize the installer for your application, you should publish the configuration file. You can also publish views and translations if you want full control over the UI and text.
# Required: Publish the configuration file
php artisan vendor:publish --tag=installer-config
# Optional: Publish views (to customize the HTML/CSS)
php artisan vendor:publish --tag=installer-views
# Optional: Publish translations (to change text or add languages)
php artisan vendor:publish --tag=installer-lang
Open config/installer.php. This file is the heart of the installer. You can configure the app name, logo, theme colors, and the exact steps your users will walk through.
return [
'name' => env('APP_NAME', 'My App'),
// Path to your logo (relative to public/)
'logo' => '/images/logo.png',
// Custom favicon (defaults to asset('favicon.png'))
'favicon' => asset('favicon.png'),
// Define the exact order of installation steps
'steps' => [
\RelayerCore\LaravelInstaller\Steps\CheckRequirements::class,
\RelayerCore\LaravelInstaller\Steps\CheckPermissions::class,
\RelayerCore\LaravelInstaller\Steps\ConfigureEnvironment::class,
\RelayerCore\LaravelInstaller\Steps\RunMigrations::class,
\RelayerCore\LaravelInstaller\Steps\CreateAdmin::class,
],
// Hook: Assign roles or permissions after the admin is created
'on_admin_created' => function ($user) {
$user->assignRole('super-admin');
},
// Hook: Run logic when the installer completely finishes
'after_install' => function () {
\Artisan::call('cache:clear');
},
];
Simply navigate to /install in your browser. The package will automatically intercept traffic to your application if the app hasn't been installed yet.
The installer is designed to be fully extensible. If your application requires users to select a pricing plan, configure a third-party API key, or choose an industry, you can add a custom step!
Use our provided Artisan command to generate the boilerplate:
php artisan make:installer-step SelectPlan
This will create a new class at app/Installer/Steps/SelectPlan.php:
<?php
namespace App\Installer\Steps;
use RelayerCore\LaravelInstaller\Contracts\InstallerStep;
class SelectPlan implements InstallerStep
{
public function id(): string { return 'plan'; }
public function label(): string { return 'Select Plan'; }
public function view(): string { return 'installer.steps.plan'; }
public function isSkipped(): bool { return false; }
public function validate(array $data = []): bool
{
// Add your validation rules
return !empty($data['plan']);
}
public function process(array $data = []): void
{
// Process and save the selected plan to the database or .env
}
}
Create the Livewire view file referenced in your step (e.g., resources/views/installer/steps/plan.blade.php). Use wire:model="state.plan" to bind inputs to the $data array passed to your validate() and process() methods.
Add your new step to the steps array in config/installer.php:
'steps' => [
\RelayerCore\LaravelInstaller\Steps\CheckRequirements::class,
\RelayerCore\LaravelInstaller\Steps\CheckPermissions::class,
\RelayerCore\LaravelInstaller\Steps\ConfigureEnvironment::class,
\RelayerCore\LaravelInstaller\Steps\RunMigrations::class,
\App\Installer\Steps\SelectPlan::class, // <-- Your custom step
\RelayerCore\LaravelInstaller\Steps\CreateAdmin::class,
],
By default, the built-in CreateAdmin step expects your User model to have name, email, and password fields.
What if your User model uses username, or first_name and last_name?
Because the installer is modular, you shouldn't try to hack the core. Instead, simply swap out the default admin step with your own!
php artisan make:installer-step SetupAdmin
process() method of app/Installer/Steps/SetupAdmin.php.config/installer.php to remove the default step and use yours:'steps' => [
// ...
\RelayerCore\LaravelInstaller\Steps\RunMigrations::class,
// \RelayerCore\LaravelInstaller\Steps\CreateAdmin::class, <-- Remove this
\App\Installer\Steps\SetupAdmin::class, // <-- Add this
],
If you just need to prompt the user for a few extra .env variables (like Timezone or Multi-Tenancy mode), you don't need a custom step! You can inject them directly into the built-in Database Setup screen via config/installer.php:
'environment_fields' => [
'MULTI_TENANT' => [
'type' => 'checkbox',
'label' => 'Enable Multi-Tenancy',
'description' => 'Host multiple businesses under one installation.',
'default' => false,
'state_key' => 'multi_tenant', // Binds to wire:model="state.multi_tenant"
],
'APP_TIMEZONE' => [
'type' => 'text',
'label' => 'Timezone',
'placeholder' => 'UTC',
'default' => 'UTC',
'state_key' => 'timezone',
],
],
CheckInstallation): Checks for the existence of the storage/installed file./install. API requests receive a 503 Service Unavailable JSON response.storage/installed marker file and automatically runs php artisan key:generate to secure the application.If you are distributing your application (e.g., via CodeCanyon, GitHub, or zip file):
.env file in your distribution with an empty or generic APP_KEY.storage/installed file in your distribution.APP_KEY for their specific installation.The Laravel Installer is open-sourced software licensed under the MIT license.
How can I help you explore Laravel packages today?