mrsafalpiya/strictly-laravel
Strictly Laravel adds opinionated strictness to your Laravel app: enforced type declarations, stricter Eloquent models, and guards against loose comparisons so bugs surface early. Lightweight, configurable, and easy to drop into existing projects.
Strictly is a Laravel package that converts a Laravel starter kit into the package's stricter conventions, driven by a published config/strictly.php. Everything you do day-to-day flows through two surfaces: the strictly:install command and that config file.
Minimal path:
composer require the package (dev dependency is the common fit, since it mostly matters at scaffold/CI time).php artisan strictly:install. This converts the kit's files and publishes config/strictly.php, declaring the vendor routes for the features your app actually has.php artisan ci:check:install and php artisan ci:check:generate to confirm you are at a clean, fully-converted baseline.Where to look first: config/strictly.php. It is the source of truth for what the package believes your app contains — not your routes files, not your starter kit choices. If the config and the app disagree, the checks fail.
First use case: an app generated with only some of the kit's auth features (say registration + email verification, no 2FA, no passkeys). As of v0.3.0 this is a supported, fully-converted state; before it, such apps were left half-converted.
Fresh scaffold flow. Generate the starter kit with the feature flags you want, then strictly:install immediately, then commit both the converted files and config/strictly.php in the same commit. Treat the published config as generated output you happen to be allowed to edit.
Upgrading a partially-featured app to v0.3.0. Two branches:
config/strictly.php: delete it, run strictly:install again. The installer republishes a config scoped to your features and converts the files it previously skipped.CI as the contract. Wire both checks into the pipeline and treat them as distinct gates:
ci:check:install → conversion completeness. Fails with <file> (not converted) for each file the installer would still convert. This is effectively a dry-run of strictly:install; a green run means "nothing left to convert."ci:check:generate → config ↔ reality consistency. Fails with config/strictly.php declares what doesn't exist for each declaration of a removed feature.Because the two checks cover different failure modes, run both. A half-converted app can pass one and fail the other.
Feature trimming as a deliberate step. When you drop an auth feature post-install, the workflow is: remove the feature's code, remove its declaration from config/strictly.php, then run both checks. Doing it in that order means the second check tells you precisely which declarations you missed.
Full-featured apps. If you kept every auth feature the kit offers, v0.3.0 is a no-op for you. No config changes, no re-install.
The installer no longer rewrites config/strictly.php. This is the headline behavioural change in v0.3.0 and the most likely source of upgrade friction. Skipped-file conversion is now automatic, but stale declarations of features you removed are your problem. If your CI goes red on ci:check:generate after upgrading, that is the cause — not a regression.
Deleting the config is a destructive fix. "Delete it and re-run strictly:install" is the clean route only if you never hand-edited the file. If you added declarations or tweaked it, deleting throws that away silently. Check git history before you delete.
Upgrade order matters. Run strictly:install after upgrading the package before you look at CI failures. In a partially-featured app, ci:check:install will report every previously-skipped file until the new installer has run — those are expected output, not bugs to chase.
Read the failure text literally. Both checks print per-item messages (<file> (not converted), config/strictly.php declares what doesn't exist). They are a to-do list, not a stack trace. Work through them one at a time; fixing a declaration often clears several downstream failures at once.
Config is an extension point, so keep edits small. Since the file is publish-and-edit and re-publishing overwrites it, document any manual additions in the commit message or alongside the file. Large bespoke edits to config/strictly.php are what turn the "just delete and re-install" escape hatch into a migration project.
Decide features early, not late. Every auth feature you add or remove after install costs you a config edit plus a check cycle. Locking the feature set at scaffold time is the cheapest path through the package.
Debugging an unclear failure. Diff config/strictly.php against the routes your app actually boots (e.g. php artisan route:list) — declaration-vs-reality mismatches are the whole category of error ci:check:generate guards against, and the route list is the ground truth.
How can I help you explore Laravel packages today?