Load configuration
ConfigLoader loads the manifest-selected definitions for HTTP or CLI into the typed configuration registry.
Lemonade uses a shared configuration, service provider and dependency injection system. HTTP requests, console commands and queued jobs run in separate runtime contexts.
Bootstrap prepares the root container for the current entrypoint: it loads typed configuration, builds the provider plan and finalizes the required registries. It does not process a specific request yet.
ConfigLoader loads the manifest-selected definitions for HTTP or CLI into the typed configuration registry.
ApplicationBootstrapper adds paths, the environment and debug mode from the current ApplicationContext.
Core, entrypoint, framework and application providers form one dependency-ordered plan.
register() declares bindings, aliases, lifetimes and tags. Runtime services are not used during this phase.
The container freezes its definition plan before provider boot() hooks may use the completed runtime container.
Routing.php and tagged registrars build and freeze the route table. Selecting a specific route happens later during HTTP dispatch.
HTTP requests, console commands and queued jobs use services registered by the application. Each execution type has its own scope, isolating state for one request, command or job.
A provider declares definitions during bootstrap. Runtime services then obtain them through the DI container.
<?php
namespace App\Providers;
use App\Services\InvoiceImportRegistry;
use Lemonade\Framework\Container\ContainerBuilderInterface;
use Lemonade\Framework\Core\ServiceProviderInterface;
final class AppServiceProvider implements ServiceProviderInterface
{
public function register(ContainerBuilderInterface $builder): void
{
$builder->singleton(
InvoiceImportRegistry::class,
InvoiceImportRegistry::class,
);
}
}A normal request passes through the global PSR-15 pipeline, routing and the selected controller. The resulting response travels back through the middleware pipeline before the kernel emits it.
The kernel passes the scope-bound PSR-7 ServerRequest into the global middleware pipeline.
Global PSR-15 middleware wrap dispatch and may return a response before routing.
The router matches the HTTP method and path, producing an immutable RouteMatch.
Route middleware wrap the selected handler; the resolver builds the controller and supplies action arguments.
The action result is normalized to a PSR-7 response and ResponseEmitter sends its status, headers and body.
HTTP methods and paths map to concrete controller actions.
The container distinguishes singleton, transient and scoped services. Request, Command and Job use their own isolated scopes.
The framework provides infrastructure and integration contracts. The application owns domain logic, content structure and concrete integrations.