lucid-arch/laravel-foundation
Lucid Architecture's Laravel Foundation provides a modular, domain-driven starting point for Laravel applications, offering conventions and base components to organize domains, features, and business logic into a clean, scalable codebase.
Read this first: lucid-arch/laravel-foundation is archived (last release 2020-09-29) and superseded by lucidarch/lucid. Treat it as a legacy dependency. Its day-to-day value is that it ships the base classes and Artisan generators for Lucid Architecture — a Laravel structure built on four primitives:
| Primitive | Role |
|---|---|
| Feature | A bounded context / mini-app (e.g. Billing, Auth) |
| Job | One use case, the entry point into a feature |
| Operation | Reusable business logic composed inside Jobs |
| Service | Adapter to an external system (API, DB, filesystem) |
Minimal setup:
composer require lucid-arch/laravel-foundation — expect constraint friction; the 2020 release targets Laravel 5.x/6.x. On a modern app you will likely need a fork or --ignore-platform-reqs in a scratch project just to inspect it.vendor:publish for the Lucid service provider) and confirm the feature root path and namespace match your PSR-4 mapping.php artisan lucid:feature Blog — scaffolds app/Features/Blog/ with Jobs/, Operations/, Services/ and a feature service provider.php artisan lucid:job Blog CreatePost — generates the Job class you will actually fill in.php artisan lucid:list — inventory features and their components; make this your first stop in an unfamiliar codebase.First use case: take a fat controller action and shrink it to three lines. The controller validates and dispatches a Job; the Job orchestrates one or more Operations; anything touching Stripe/S3/an HTTP API moves into a Service. That single refactor teaches you 90% of the package.
The layering contract. Controllers and console commands should never contain business logic — they dispatch a Job. Jobs orchestrate Operations and Services but should not contain raw I/O. Operations are pure-ish and reusable across Jobs. Services are the only place that knows about the outside world. Enforce this in review; it is the entire point of the package.
One Job per use case. Name them after the intent (CreatePost, PublishPost, ArchivePost), not the entity. lucid:job output is deliberately near-empty — the generator gives you a home for the code, not the code.
Feature isolation. Cross-feature calls go through the other feature's Job (its public surface), never by reaching into another feature's Operations or models. When you find yourself importing App\Features\Billing\Operations\... from inside App\Features\Auth, you have found a design bug.
Dispatching. The Feature base class exposes helpers to run Jobs, and Jobs are container-resolved, so constructor injection works normally. Run synchronously when the caller needs the result; push onto the queue when it does not. Keep a consistent convention across the team — mixing dispatch and direct new Job() calls is where these codebases rot.
Per-feature wiring. Register each feature's service provider (routes, event listeners, config) from the feature itself, not from AppServiceProvider. That is how features stay portable. If the package does not auto-discover providers in your Laravel version, register them explicitly in a single bootstrap list.
Testing. The structure pays off here: instantiate a Job directly with a fake payload and assert on its return value, bypassing HTTP entirely. Bind Service interfaces to fakes in the container and every Job that depends on them becomes a unit test. Aim for thin feature tests over controllers and thick tests over Jobs and Operations.
Audit cadence. Run lucid:list before and after a refactor. Component sprawl (a feature with 40 Jobs) is the signal to split the feature, and the listing command makes that visible in a way a file tree does not.
lucidarch/lucid (renamespaced, restructured) rather than planning new work on this package. Migrate behind a test suite that exercises Jobs directly — those tests survive the move; controller tests may not.vendor/ — it is small, and the base classes are readable in an afternoon. Do not expect Stack Overflow to save you.composer dump-autoload. Verify the feature namespace in config matches the autoload.psr-4 entry exactly; a mismatch is the single most common setup failure.php artisan config:clear. In CI this bites silently.handle().Job/Operation to add shared logging, timing, or transaction wrapping is the intended customization seam; global middleware-style hooks do not exist here.How can I help you explore Laravel packages today?