qcod/laravel-app-settings
Add a settings manager with UI to your Laravel app. Settings are stored in the database and cached for zero-query performance, with configurable inputs, sections, and styling (Bootstrap 4 by default). Includes a facade for easy access.
from_email/from_name identity, date-format preferences, upload-a-logo, and simple on/off toggles are all declaratively defined as sections → inputs with per-field rules, value defaults, hints, and data_type casts. This lets you answer "can we make X configurable?" with "yes, one config entry" rather than "that's a ticket."setting_group (a closure like 'user_'.auth()->id(), or runtime setStorageGroup()) unlock white-label demos and enterprise "your logo, your sender address" conversations without a bespoke build per prospect.boolean inputs and grouped settings make it tempting, this explicitly informs a no decision: it is a settings store, not a flag system. No targeting, no gradual rollout, no audit log, no evaluation SDK. If experimentation is on the roadmap, budget separately.Adopt when most of these are true:
config/app_settings.php is fast and diffable, but you get no typed DTOs, no IDE autocompletion, and no compile-time safety.disk and path, plus a mutator escape hatch for resizing or custom storage (e.g. Intervention Image). Writing this by hand is the single most tedious part of a custom build.section_class, input_class, submit_btn_text, etc.) or supply your own Blade view via setting_page_view and @include('app_settings::_settings'). The default styling is opinionated; plan for an hour of theming, not zero.setting() helper work as a plain key-value store for API-only contexts, provided you set 'remove_abandoned_settings' => false so undefined fields aren't purged on save.Look elsewhere when any of these are true:
spatie/laravel-settings is the stronger choice for code-first, strongly typed settings classes with migrations and encryption. This package's data_type casts (int, bool, array, string) and accessor/mutator hooks cover simple cases, not a typed settings domain.boolean inputs into a flag system.setting_group closure approach is elegant for light per-user grouping, but it's fragile in queued jobs and CLI/Artisan contexts where auth()->id() doesn't exist, and per-tenant cache invalidation gets complicated at scale.config/ files already cover it, take the zero-dependency path. Adopt this only when humans must change values without a release.Two things I'd verify in a two-day spike before committing: (1) whether the package's settings route ships behind any middleware — assume you must attach your own auth/can: gate, since an unauthenticated settings page is a privilege-escalation bug, not a styling issue; and (2) the remove_abandoned_settings default and how it interacts with any non-UI setting()->set() calls you make from code, because a UI save can silently delete data you wrote programmatically.
For executives — the one-paragraph version. We have a recurring, low-differentiation need: letting non-engineers change things like the app name, the sender address on transactional email, logo and branding assets, and maintenance messaging, without a deploy. Building that ourselves is one to two sprints of engineering plus permanent upkeep. qcod/laravel-app-settings gives us that surface — database-backed settings with caching, per-field validation, file uploads, and an optional UI — for the cost of a Composer dependency, one migration, and a config file. It's MIT-licensed, so there's no procurement, no seat cost, and no lock-in. The tradeoff is community size: it's a small, single-maintainer project, but it's also small enough that if it were ever abandoned we could fork it in a day. Recommendation: approve a short timeboxed spike to put it behind our auth gate and use it for branding and email-identity settings, capped at a modest field count. Explicitly out of scope: feature flags, secrets, and anything requiring an audit trail.
For engineering — what we're actually signing up for. It's a thin UI layer over qcod/laravel-settings: a settings table, a cached key-value store, and a Blade-rendered form generated from config/app_settings.php. We get a setting() helper and an AppSettings facade, closures for dynamic select options (App\City::pluck(...)) and for most field values, accessor/mutator hooks for custom transforms, and grouped storage for per-user or per-tenant scoping. It ships Bootstrap 4 markup, overridable via class config or a full view swap. Four things we own, not the package: (1) Authorization — we must gate the settings route behind our own middleware; do not assume it's protected. (2) Secrets policy — settings are stored in plaintext in the DB and the documented pattern serializes all settings into a Blade template as window.App = {!! json_encode(...) !!} for JS access. Never put API keys or credentials in here; write that rule down. (3) Environment promotion — configuration stops being code. Staging and production settings will drift, settings must be added to backup/restore and DR runbooks, and "it works in staging" no longer implies the same config values. (4) Cache semantics — reads are cached, so any write that bypasses the package (raw SQL, seeders, direct DB edits) won't be reflected until the cache clears. Also set remove_abandoned_settings => false if we mix UI-defined fields with programmatic setting()->set() calls, or a UI save will delete the latter.
The ask: a two-day spike — install, gate the route, define five real settings (logo upload, app name, from_email, from_name, one maintenance boolean), theme it to our CSS, and confirm the cache and cleanup behavior. Ship if it clears; revisit if typed settings, per-tenant scale, or audit requirements arrive on the roadmap.
How can I help you explore Laravel packages today?