Service Container

Monad does not have a service container. There is no bind(), no resolve(), no auto-wiring, and nothing to configure before a service becomes usable. If you're coming from a framework with a service container or dependency-injection container: there's no app()->make() call and no constructor-injected dependency to satisfy. This is a deliberate design choice — "light scaffolding: if it's not necessary, don't implement it" — not a gap waiting to be filled.

How services actually work

Almost every service (Route, View, DB, Session, Console, Mediator, and the rest) is a static class. You call it by its fully-qualified name, the same way you'd call any other PHP static method — no resolving step in between:

use Monad\Clarity\Services\DB;
use Monad\Clarity\Services\Route;
use Monad\Clarity\Services\View;

Route::get('/users', function () {
    $users = DB::run('SELECT id, email FROM users')->fetchAll();

    return View::render('Users/index', ['users' => $users]);
});

Some services take one-time setup — DB::configure('default', $config), View::configure($viewPath), Session::configure($lifetimeSeconds) — called once from config/bootstrap.php, the single shared boot path for web, CLI, and scripts. That's configuration, not resolution: nothing gets bound to an interface, and nothing decides at runtime which implementation to hand back.

The exceptions: Cache, HttpClient, Files, and the LLM adapters

A handful of services are instantiated rather than called statically, because each implements a PSR instance interface (or, for the LLM adapters, needs its own per-provider credentials) — not because the "no container" rule has a loophole. You still construct each one yourself, with no container resolving it for you:

use Monad\Clarity\Services\Cache;
use Monad\Clarity\Services\HttpClient;
use Monad\Clarity\Services\Files;
use Monad\Clarity\Services\LLMAdapters\Anthropic;

$cache = new Cache(driver: Cache::DRIVER_DATABASE);       // PSR-16 CacheInterface
$client = new HttpClient();                                // PSR-18 ClientInterface
$files = new Files(adapter: Files::ADAPTER_FILESYSTEM, basePath: '/var/uploads');
$llm = new Anthropic(apiKey: $apiKey, httpClient: $client); // needs its own credentials

There's no ambient Cache::configure()-style singleton for any of these — an app that wants one shared instance builds it once itself (a small app-owned factory function or a static holder in an App\Services\ class) rather than Clarity providing one for you.

Next steps

  • Caching — the full Cache API and its three drivers.
  • HttpClient and Files — the other two PSR/instance-based services.
  • LLM — the provider adapters and why each needs its own credentials.
  • RoutingRoute, the service you'll call most.
  • FAQ — quick, direct answers to other "does Monad have X" questions.