sashalenz / laravel-settings-ui
Declarative, nestable runtime settings for Laravel โ fluent schema, pluggable stores, secure secrets, resilient cache, config() overlay and bundled admin UI.
Requires
- php: ^8.3|^8.4|^8.5
- illuminate/console: ^11.0|^12.0|^13.0
- illuminate/contracts: ^11.0|^12.0|^13.0
- illuminate/database: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
- illuminate/validation: ^11.0|^12.0|^13.0
- livewire/livewire: ^3.5|^4.0
- spatie/laravel-package-tools: ^1.16|^1.17|^1.93
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.18
- nunomaduro/collision: ^8.0
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
- phpstan/phpstan: ^2.0
Suggests
- aws/aws-sdk-php: Required to use AwsSecretsManagerDriver.
- google/cloud-secret-manager: Required to use GcpSecretManagerDriver.
- spatie/laravel-activitylog: Bind ActivitylogRecorder to mirror setting changes into an existing activity log.
Provides
None
Conflicts
None
Replaces
None
README
Declarative, nestable runtime settings for Laravel โ fluent schema, pluggable stores, secure secrets, resilient cache, transparent config() overlay, and a bundled responsive admin UI built with Livewire and Tailwind CSS.
โจ Features
- Code-Authoritative Declarations: Settings are defined in strongly typed PHP classes, never in the database.
- Zero-Coupling
config()Overlay: Application code continues to readconfig('group.key')without any dependency on the settings machinery. - Deep Hierarchical Nesting: Groups, subgroups, cards, sections, and fields mirror full dotted paths (
group.section.key). - Pluggable Storage Backends: Database, Encrypted Database, File (JSON/YAML), and external Secret Stores (Vault, AWS Secrets Manager, etc.).
- Pluggable & Secure Secrets Engine:
- Masked values in HTML and Livewire states.
- Zero-plaintext leaks in logs and exception traces.
- Rate-limited and permission-gated "Click to Reveal" action.
- Resilient & Stampede-Protected Cache:
- Stores primitive values only (zero risk of
__PHP_Incomplete_Classserialization bugs). - Schema fingerprinting & version-stamped keys.
- Cache stampede prevention via cache locks.
- Queue worker / Octane auto-refresh hooks.
- Stores primitive values only (zero risk of
- Full Audit History & Revert:
- Automatically records user, timestamp, before/after values, and source.
- One-click rollback to prior versions.
- Modular & Domain Discovery:
- Register settings from packages, modules, or domains (
Settings::register(...)orSettings::discover(...)). - Composer
extra.laravel-settingsdiscovery.
- Register settings from packages, modules, or domains (
- Seeder Engine & CLI:
SettingsSeederfor idempotent seeding (syncMissing()andforceSync()).- Artisan commands:
settings:sync,settings:seed,settings:doctor,settings:clear-cache.
๐ฆ Installation
Install via Composer:
composer require sashalenz/laravel-settings-ui
Publish configuration and migrations:
php artisan vendor:publish --tag="settings-config" php artisan vendor:publish --tag="settings-migrations" php artisan migrate
๐ Quick Start
1. Declare a Setting Schema
Create a schema class implementing DeclaresSettings:
namespace App\Settings; use SashaLenz\SettingsUi\Contracts\DeclaresSettings; use SashaLenz\SettingsUi\Schema\Field; use SashaLenz\SettingsUi\Schema\Group; final class GeneralSettings implements DeclaresSettings { public function schema(): Group { return Group::make('general') ->label('General Settings') ->icon('heroicon-o-cog') ->fields([ Field::text('site_name') ->label('Website Name') ->default('My App') ->rules(['required', 'string', 'max:255']), Field::boolean('maintenance_mode') ->label('Maintenance Mode') ->default(false), Field::text('api_token') ->label('API Secret Token') ->secret() ->store('secrets'), ]); } }
2. Register the Schema
In your config/settings.php:
'schemas' => [ \App\Settings\GeneralSettings::class, ],
Or programmatically in any ServiceProvider:
use SashaLenz\SettingsUi\Facades\Settings; public function boot(): void { Settings::register([ \App\Settings\GeneralSettings::class, ]); // Or discover all settings across domain modules: Settings::discover([ app_path('Domain/*/Settings'), ]); }
3. Read Values Transparently
// Stored database value automatically overlays config file default: $siteName = config('general.site_name'); // Or using the Settings facade: $siteName = Settings::get('general.site_name');
๐ Secrets Management
Mark fields as secret to encrypt them and prevent plaintext exposure in forms and logs:
Field::text('stripe_secret') ->secret() ->store('secrets')
Supported Drivers:
encrypted-db: Encrypted locally in your database using Laravel'sAPP_KEY.env: Resolves from.envenvironment variables.vault: HashiCorp Vault KV v1/v2 engine.aws: AWS Secrets Manager.
๐ฑ Seeding Settings
Seed declared defaults safely without overwriting existing settings:
use SashaLenz\SettingsUi\Database\Seeders\SettingsSeeder; class DatabaseSeeder extends Seeder { public function run(): void { $this->call(SettingsSeeder::class); } }
Or via Artisan CLI:
php artisan settings:seed php artisan settings:seed --group=general --force
๐ฅ Admin UI
Mount the routes in your routes file (e.g., routes/web.php):
use SashaLenz\SettingsUi\Facades\Settings; Route::prefix('admin')->middleware(['web', 'auth'])->group(function () { Settings::routes(); });
Available routes:
/admin/settingsโ List of setting groups/admin/settings/{group}โ Group editor form/admin/settings/historyโ Audit change log & revert/admin/settings/schemaโ Read-only schema inspector
๐งช Testing
composer test
composer format
composer analyse
๐ License
The MIT License (MIT). Please see License File for more information.