Laravel Settings
A Composer package - `satheez/laravel-settings` - that gives Laravel apps a dedicated database table and concise helper API for runtime settings. It ships with package auto-discovery, publishable migration and config files, caching, optional encryption, and Pest coverage for the core set/get flow.
Problem
Laravel apps often collect settings in three different places: .env for deploy-time values, config files for defaults, and one-off database tables for runtime values. That split works until product or operations settings need to change without a deploy. At that point, teams either add ad hoc tables per feature or build another thin settings wrapper inside the app.
The goal of satheez/laravel-settings is to make the runtime case small and reusable: install one package, publish a migration, and read or write settings through Laravel-native helpers.
Constraints
- Composer install - adoption needs to start with
composer require satheez/laravel-settings. - Laravel-native service provider - the package should register through Laravel package auto-discovery and bind a
settingsservice into the container. - Dedicated
settingstable - runtime values need one predictable table with a unique key column and a serialized value column. - Concise helper API - reads and writes should be possible through
settings(),settings_get(), andsettings_set()without requiring a custom model in the host app. - Publishable migration and config - apps should be able to publish the package migration and tune cache or encryption flags through config.
- Tests for the core contract - the package needs coverage around setting values, reading values, and returning defaults for missing keys.
Key decisions
- Helper-first API -
settings(['foo' => 'bar'])writes one or more values, whilesettings('foo')reads a value.settings_get()andsettings_set()make the operation explicit when that reads better in application code. updateOrInsertstorage - writes are idempotent at the database layer. The package can overwrite an existing key or create it without a separate existence check.- Serialized values - values are serialized before storage and unserialized on read, allowing the table to keep one text column instead of requiring a rigid schema per value type.
- Cache layer - reads and writes use Laravel’s cache when enabled, with keys namespaced as
laravel-settings|table|{key}and a configurable TTL. - Encryption configuration - the published config exposes encryption and cache flags so applications can choose how aggressively to protect or cache stored settings.
- Spatie package tools -
spatie/laravel-package-toolshandles package registration, the publishablecreate_settings_tablemigration, and thelaravel-settingsconfig file. - Composer auto-discovery -
composer.jsonregisters the service provider and facade alias, keeping installation close to the normal Laravel package workflow.
Outcome
Laravel Settings is published as satheez/laravel-settings with an MIT license. The package targets PHP ^8.1, requires illuminate/contracts ^9.0, and uses spatie/laravel-package-tools for the Laravel package surface.
The package includes Pest tests for the behavior that matters most at this size: setting values through the helper API, reading them back through both settings() and settings_get(), and returning a default value when a key does not exist.
What I’d do differently
The package solves the narrow runtime-settings problem, but the public documentation is still too close to the package skeleton. I would improve the README and Packagist description, document the cache and encryption behavior more clearly, and expand tests around non-string values and config flags so the package contract is easier to trust before adoption.