Adding dependencies
Dependencies are declared in Curie.toml. Add them by editing the file directly, or use curie add to let Curie resolve the latest version and write the entry for you.
Editing Curie.toml by hand
Each entry is "group:artifact" = "version". Production dependencies go under [dependencies]; test-only dependencies go under [test-dependencies]:
[dependencies] "com.fasterxml.jackson.core:jackson-databind" = "2.17.2" "com.google.guava:guava" = "33.4.8-jre" [test-dependencies] "org.junit.jupiter:junit-jupiter" = "6.0.3" "org.assertj:assertj-core" = "3.26.0"
An empty version ("") means the version comes from a BOM — see BOM imports below. If no BOM provides the version, the build fails immediately with an error.
Excluding transitive dependencies
Some dependencies pull in transitive dependencies you don't need. Use the detailed form with an exclusions list to prevent specific artifacts from appearing on the classpath:
[dependencies] # commons-codec is only needed by commons-compress's lz4/snappy compressors "org.apache.commons:commons-compress" = { version = "1.27.1", exclusions = [ "commons-codec:*", ] }
Each exclusion is a "group:artifact" string. Exclusions are transitive: if A depends on B which depends on C, excluding C on A will prevent C from appearing anywhere in the resolved tree below A.
Use "*:*" to exclude all transitive dependencies of an artifact (keeping only the artifact itself):
"com.example:fat-lib" = { version = "1.0", exclusions = ["*:*"] }
Curie also honours <exclusions> declared in upstream POM files. If a library's own POM excludes a transitive dependency, Curie respects that exclusion automatically — matching Maven's behaviour.
Major-version conflicts
Curie resolves version conflicts with Maven's nearest-wins rule: when two paths in the dependency graph need different versions of the same group:artifact, the one declared closest to your project wins. That is usually what you want — but a major-version difference is dangerous: keeping 2.x when a transitive dependency was compiled against 5.x can fail at runtime with NoSuchMethodError or NoClassDefFoundError.
So when a discarded candidate's major version differs from the version Curie keeps, the build fails with an explanation:
dependency version conflict (major-version mismatch)
com.google.guava:guava — keeping 33.0-jre, but org.example:lib:1.2 requires 25.1-jre
A major-version difference can cause runtime errors (missing classes/methods).
Fix the version, exclude the transitive dependency, or — if intentional —
allow it in Curie.toml:
"com.google.guava:guava" = { version = "33.0-jre", allowVersionConflict = true }
You have three ways to resolve it:
- Upgrade your declared version (or the dependency that pulls the older one) so the majors agree.
- Exclude the transitive dependency that needs the other major (see exclusions) if it is not actually required.
- Accept it — when you know the kept version is binary-compatible — by setting
allowVersionConflict = trueon that dependency:
[dependencies] "com.google.guava:guava" = { version = "33.0-jre", allowVersionConflict = true }
allowVersionConflict only silences the error for that one coordinate; resolution is unchanged (nearest-wins still keeps your version). Minor and patch differences never trigger this check — they are resolved silently, matching Maven. The same rule applies to [test-dependencies].
curie add
curie add queries Maven Central for the artifact, picks the latest version, and writes the entry into Curie.toml:
Resolving latest: com.google.guava:guava Added com.google.guava:guava = "33.4.8-jre" → [dependencies]
Pin to a specific version with @version:
Added com.google.guava:guava = "33.2.1-jre" → [dependencies]
Fat JAR shading (shadeAll, shade, relocations)
When a project has a [fat-jar] section, Curie can produce a self-contained -fat.jar. The global default for whether dependencies are bundled is controlled by shadeAll:
[fat-jar] enabled = true shadeAll = true # default: bundle (shade) deps unless overridden [[fat-jar.relocations]] from = "com.google.common" to = "com.example.shaded.com.google.common"
Per-dependency control:
shade = true/false(the legacyfatJarkey is still accepted)- A
relocationsarray on a dependency forces it to be shaded and applies the rules only to classes from that dependency (Curie checks that the "from" packages do not appear in other bundled deps; if they do you get an error suggesting to move the rule to the top-level[[fat-jar.relocations]]).
[dependencies] "com.google.guava:guava" = { version = "33.2", relocations = [ { from = "com.google.common", to = "com.example.shaded.com.google.common" } ] } "org.slf4j:slf4j-api" = { version = "2.0", shade = false }
curie add flags
| Flag | Effect |
|---|---|
--test | Add to [test-dependencies] instead of [dependencies] |
--bom | Add to [bom-imports]; subsequent BOM-managed deps can omit the version |
--test-bom | Add to [test-bom-imports] |
--annotation-processor | Add to [annotation-processors] |
# test dependency curie add --test org.assertj:assertj-core@3.26.0 # add a BOM, then a BOM-managed dep (version will be "") curie add --bom com.fasterxml.jackson:jackson-bom@2.17.2 curie add com.fasterxml.jackson.core:jackson-databind # annotation processor curie add --annotation-processor org.projectlombok:lombok@1.18.32
curie remove
Remove an entry from whichever section it appears in:
Removed com.google.guava:guava from [dependencies]
BOM imports
A BOM (bill of materials) is a POM-packaged artifact whose <dependencyManagement> section pins versions for a family of related artifacts. Declare BOMs under [bom-imports]; all entries are applied in order (later wins on collision):
[bom-imports] "com.fasterxml.jackson:jackson-bom" = "2.17.2" [dependencies] # empty version → resolved from the BOM above "com.fasterxml.jackson.core:jackson-databind" = "" "com.fasterxml.jackson.core:jackson-annotations" = ""
Use [test-bom-imports] for BOMs that only apply to test-scope dependencies:
[test-bom-imports] "org.junit:junit-bom" = "5.11.0" [test-dependencies] "org.junit.jupiter:junit-jupiter" = ""
BOM imports can also be inherited from a workspace root — see Workspaces.
For how Curie resolves transitive dependencies, applies nearest-wins conflict resolution, verifies checksums, and handles offline mode, see Resolver & checksums.