Dependency tree
curie deps prints the full transitive dependency tree and explains version-selection decisions. It answers "what is on my classpath and why?" without running a build — filling the gap that mvn dependency:tree covers for Maven users.
Print the tree
Dependencies for jackson-bom-greeter v0.1.0
└─ com.fasterxml.jackson.core:jackson-databind:2.17.2
├─ com.fasterxml.jackson.core:jackson-annotations:2.17.2
└─ com.fasterxml.jackson.core:jackson-core:2.17.2
curie deps resolves POMs (using the local ~/.m2 cache after the first build) but does not download JARs — it's a read-only query command.
Explain a version choice (--why)
Use --why group:artifact to see which introduction path won and what was skipped:
com.fasterxml.jackson.core:jackson-core:2.17.2 (depth 1)
Introduced by:
[declared] → jackson-databind:2.17.2 → jackson-core:2.17.2 (chosen — depth 1)
No version conflicts.
When nearest-wins resolved a conflict you'll see the skipped path too:
com.example:shared-lib:1.0 (depth 1)
Introduced by:
[declared] → lib-a:1.0 → shared-lib:1.0 (chosen — depth 1)
Skipped (nearest-wins):
[declared] → lib-b:1.0 → lib-c:1.0 → shared-lib:2.0 (depth 3)
→ version 1.0 wins because it is at depth 1 (shallowest path wins).
Test dependencies (--tests)
By default curie deps shows production ([dependencies]) deps. Pass --tests to inspect the test closure instead:
Test dependencies for my-app v0.1.0
├─ org.junit.jupiter:junit-jupiter:5.11.0
│ ├─ org.junit.jupiter:junit-jupiter-api:5.11.0
│ └─ org.junit.jupiter:junit-jupiter-params:5.11.0
└─ org.junit.jupiter:junit-jupiter-engine:5.11.0
└─ org.junit.platform:junit-platform-engine:1.11.0
Offline mode
If the POM cache is already warm (e.g. after running curie build), add --offline to avoid any network calls:
Dependencies for my-app v0.1.0
└─ …
Conflict resolution rules
Curie follows Maven's standard rules:
- Nearest wins — when the same
group:artifactappears at two depths, the shallower version wins. - First declared wins — at equal depth, the artifact declared first in
[dependencies](or the POM that introduced it first) takes precedence. - Top-level BOM beats transitive explicit — your
[bom-imports]overrides any version a transitive POM hard-codes.
--why always shows both the winning path and any skipped losers, so you can confirm that the correct rule was applied.