illuminate/reflection
Illuminate\Reflection wraps PHP's native ReflectionClass with Laravel-specific helpers for inspecting methods, properties, traits, attributes, and doc comments. It underpins the service container, route model binding, and much of the framework's internal introspection.
illuminate/reflection is a first-party subtree split of laravel/framework (MIT, ~35k stars on the monorepo, released on the framework cadence). The real decision is how much of our product surface we let touch it — not whether to procure it.#[Inject], custom attributes), or "resolve this class the way the container would" should be scoped against Reflector first; only build custom reflection when we've documented a concrete gap.Reflector calls behind a thin internal adapter (e.g., App\Support\ClassInspector). That preserves the productivity win while containing upgrade churn across Laravel majors, where internal APIs are explicitly not covered by semver.Dependents: 0 is a metadata artifact of subtree splits — every laravel/framework install transitively contains this code. We should correct the record internally so the package isn't re-litigated.Adopt (use directly, behind an adapter) when:
ReflectionClass plumbing.@inject / #[Inject].getParameters(withDefaults: true)) for CLI prompts, generated request objects, or config defaults.Look elsewhere when:
ReflectionClass / ReflectionMethod; Reflector is a high-level wrapper and will feel lossy.Container::make() / app(); there is no product value in routing through reflection.symfony/property-access or core Reflection*.To executives: "This isn't a new vendor — it's part of the Laravel framework we already run in production, under MIT, maintained by the same team, shipped on the same release train. It gives our engineers the standard Laravel way to inspect and instantiate classes, which is the machinery behind auto-discovery, plugin registration, and generated API documentation. Cost is zero, procurement is zero, and the risk is a coupling risk rather than a supply-chain risk — which we manage by keeping it behind one internal wrapper. Net: we ship discovery and auto-configuration features faster, and we don't accumulate three homegrown reflection utilities to maintain."
To engineering: "Use Illuminate\Support\Reflector as the default for anything that needs container semantics — canBeInstantiated(), getConstructor(), getParameters(withDefaults: true) — and keep native ReflectionClass for deep inspection and attributes. Two hard rules: (1) no direct Reflector calls in domain code, go through App\Support\ClassInspector so a Laravel major can't break us in fifty places; (2) cache reflection results, never re-reflect in a loop. Also note make()/resolve() don't touch the container unless you pass it — that's the most common bug we'll hit."
To product/design partners: "This unlocks capabilities rather than features: the app can discover and wire up new handlers, commands, and integrations without a developer editing a registry file each time. Practically, that's faster iteration on extensibility and fewer 'you forgot to register it' defects."
How can I help you explore Laravel packages today?