phug/dependency-injection
Phug Dependency Injection is a lightweight PHP DI container offering autowiring, lazy service resolution, and flexible configuration for clean, testable applications.
What the package is. phug/dependency-injection is a small, single-purpose DI container extracted from the Phug ecosystem (a PHP port of the Pug template engine). The listed repository (phug-php/util) is a monorepo rather than a dedicated package repo, which tells us the component was factored out of a utility bundle rather than designed as a standalone, community-facing container.
Architecture fit. Poor as a primary container in Laravel. Laravel already ships Illuminate\Container\Container, wired into the framework's service providers, facades, contextual binding, deferred providers, and config:cache compilation. Introducing a second container creates two resolution graphs, two lifetimes, and an ambiguity about which container owns a binding. The only defensible architectural role is inside the Phug rendering pipeline: if you adopt Phug for Pug-style templates in Laravel, the renderer's own dependency resolution may expect this container's contract, and swapping in Laravel's container requires an adapter that Phug does not officially maintain.
Integration feasibility. Low effort, low payoff. The package is MIT-licensed, small, and Composer-installable with no native extensions or exotic requirements — a spike is a few hours. But there is no Laravel service provider in the package, no published PSR-11 conformance statement, and no facade. Every integration point (provider registration, binding translation, singleton scoping) is bespoke code your team writes and owns.
Technical risk. Moderate, concentrated in provenance rather than code:
composer.json autoload map, and tag history actually correspond to the code being installed before it enters the dependency tree.Key questions for the maintainer / your architect:
phug/renderer in a way that forces version lockstep?Illuminate\Container cleanly, obviating this dependency entirely?util release cadence?Stack fit. PHP 8.x / Laravel 10–12 is compatible in principle. The mismatch is conceptual, not syntactic: Laravel's container is opinionated about auto-wiring, interface binding, and contextual injection, and this package duplicates that surface with different semantics. Two containers in one request is a smell unless the boundary is a library-internal sandbox — which is precisely the only boundary worth drawing here.
Recommended posture: do not adopt directly. Treat phug/dependency-injection as a transitive concern that appears only if and when you bring Phug into the stack. In that case, pin it explicitly in composer.json (not left floating to ^x), and isolate it behind an adapter so the rest of the application never resolves from it.
If adopted (Phug-in-Laravel scenario), the migration path is:
get/has behavior and exception types.PhugContainerAdapter implementing whatever Phug's container contract is, delegating to Illuminate\Container. This is the highest-value artifact — it lets you delete the package later without touching call sites.app() access from library code.Compatibility and sequencing. Block on the PSR-11 question before scheduling work. Sequence: (a) provenance verification → (b) PSR-11 spike → (c) adapter → (d) parity tests → (e) production shadow-read. Do not sequence this alongside an Octane migration; long-lived workers will expose container-scoped state bugs that are hard to attribute when two variables change at once.
Exit criterion. If the adapter proves viable, you should be able to remove phug/dependency-injection from require within one quarter with zero application-code changes. If you cannot, that itself is the finding — the coupling is deeper than the package's 1-star footprint suggests.
Maintenance. Nominal direct cost (one pinned dependency, one adapter file) but non-trivial cognitive cost: every engineer must know which container owns what. Document the boundary in the architecture decision record and enforce it in code review, or the second container will leak.
Support. No commercial support, no SLA, single-maintainer risk. Your team is the support tier. Budget for eventual vendoring: because the package is MIT and presumably small, forking into an internal namespace is a realistic fallback and should be pre-approved rather than negotiated during an incident.
Scaling. Request-scoped containers scale fine; the risk is Octane and queue workers, where a container's singleton cache persists across requests. Verify that the container does not hold request-scoped state in static properties. If it does, reset it per-request in a middleware or terminate the adoption.
Failure modes to monitor:
Ramp-up. A new engineer needs roughly half a day to understand the adapter and the container boundary, plus the ADR. That is acceptable only if the boundary is genuinely small. If onboarding docs start explaining resolution order, the integration has exceeded its budget.
TPM recommendation. Score this as low priority / watchlist, not adopt. The 7.46 quality score reflects clean, MIT-licensed code; the 28.87 opportunity score correctly reflects that Laravel does not need a second container. Spend engineering time on the adapter only if Phug adoption is already committed for independent product reasons — and in that case, the deliverable is the adapter and the exit path, not the package.
How can I help you explore Laravel packages today?