⚠️ Beta. The analyzer is real and tested, but young. Please report false positives — they are the bug class we care about most.
Command-line tooling for Illuma dependency-injection projects.
One command today: illuma lint reads your TypeScript source, reconstructs the DI graph without running your app, and tells you which containers would fail at bootstrap(). Built for the failure mode where AI coding agents (and humans) wire ServiceA → ServiceB → ServiceA, or inject a token nobody registered, and only find out at runtime.
[i401] Circular dependency detected while resolving "NodeToken[_ProjectsService]":
NodeToken[_ProjectsService] -> NodeToken[_ProjectsModel] -> NodeToken[_ProjectsService]
bun add -d @illuma/cliRequires @illuma/core >= 2.4.0 in the analyzed project — an optional peer dependency; the analyzer mirrors that version's semantics.
illuma help # commands and exit codes
illuma help lint # everything `illuma lint` acceptsilluma lint # uses ./tsconfig.json
illuma lint --tsconfig ./apps/api/tsconfig.json
illuma lint --strict # also report cycles the runtime tolerates by design
illuma lint --json # machine-readable output for CI
illuma lint --fail-on-warn # treat warnings as failures tooExit codes: 0 nothing to report · 1 problems found · 2 tool or usage error. A bare illuma with no command is a usage error (2), not a clean run.
Programmatic:
import { analyze } from "@illuma/cli";
const result = await analyze({ tsconfig: "./tsconfig.json", strict: true });
for (const cycle of result.cycles) console.log(cycle.path.join(" -> "));
for (const d of result.diagnostics) console.log(d.code, d.message);Codes and messages mirror @illuma/core's own InjectionError output, so a report can be matched against a real crash. Our advice lives in a separate hint field, never in message.
| Code | Failure | Fires at runtime |
|---|---|---|
i401 |
Circular dependency | bootstrap() / instantiation |
i600 |
Two global tokens sharing a name under different classes | module eval — before any container exists |
i102 |
provide(X) / nodeInject(X) on a class that was never made injectable |
registration / injection |
i103 |
Provider object matching no known shape | provide() |
i200 |
Invalid alias target | provide() |
i100 |
Two implementations for one token on one container | provide() |
i201 |
Self-referencing alias | provide() |
i202 |
self and skipSelf together |
injection |
i400 |
No provider for an injected token (warning — see below) | bootstrap() / first get() |
no-coverage |
The run found nothing to analyze | — |
i400 is deliberately a warning: provider sets can be built dynamically in ways static analysis cannot see, so we do not yet claim a proof. Promoting it to an error where unresolvability is provable is the next milestone.
Illuma discovers its edges by executing factories and constructors in a dry-run probe at registration time (see docs/ILLUMA_INTERNALS.md), so a static tool cannot perfectly reproduce the runtime graph.
- ✅ A high-value lint over the statically visible graph, using the runtime's own error contract.
- ❌ Not a verifier. A clean report does not prove a clean runtime graph.
Known limits in this release:
- Reachability is not modelled. A cycle among classes your app never resolves is still reported, even though that program runs fine.
- Single container. Parent/child topology,
self/skipSelfscoping, andInjector.get()/.produce()targets are recorded but not yet walked. defer/asyncseams are not modelled, so--strictcannot surface cycles hidden behind them yet — today it only adds transparent-only cycles.- A
nodeInjectthat cannot run with the injection context open (a plain method, a stored callback, after anawait) is not yet reported.
A run that indexes nothing reports no-coverage rather than "no problems found" — a mistyped --tsconfig must never look like a clean bill of health.
| Doc | What's in it |
|---|---|
| AGENTS.md | Start here before contributing. What you must know to not make this tool confidently wrong. |
| docs/ILLUMA_INTERNALS.md | How Illuma builds its graph, every dependency form, the defeaters, the contracts we mirror. |
| docs/ARCHITECTURE.md | Our design: pipeline, modules, data model, output, exit codes. |
| docs/ROADMAP.md | Phased plan against a census of every way an Illuma container can fail. |
MIT — created by bebrasmell.