Skip to content

Dependency Management

TheMeinerLP edited this page Aug 1, 2026 · 2 revisions

How Falco resolves and declares its dependencies: where repositories are configured, notable version catalog entries, and why several dependencies are compileOnly rather than implementation.

Repositories live only in settings.gradle.kts

All repository configuration is centralised in dependencyResolutionManagement in settings.gradle.kts. No module build file declares its own repositories { } block — see Build Setup for why a project-level block would be actively harmful here (it would take precedence and silently drop the OneLiteFeather repository).

Notable version catalog entries

The libs version catalog in settings.gradle.kts pins a few things that are easy to miss the reason for:

  • jmh and jmhPlugin versions. The mycelium BOM (libs.mycelium.bom) does not manage JMH, so both the benchmark harness and the Gradle JMH plugin need an explicit version declared here.
  • adventureBom (5.1.1). Production modules receive Adventure transitively through Minestom, which is compileOnly and therefore never reaches a runtime classpath (see below). The benchmarks module runs its code for real and needs Adventure at runtime, so it imports the Adventure platform directly. This version has to be kept in sync by hand with whatever version Minestom itself resolves to.
  • slf4j.simple. Only falco-demo needs an SLF4J binding. The library modules log through the API and leave the choice of binding to the consumer; a demo that actually runs would otherwise greet the user with "No SLF4J providers were found" before printing anything of its own.
  • fastutil (8.5.18, explicit version). Minestom declares fastutil at runtime scope, so it never reaches a compile classpath. falco-light's equivalence test and the comparison benchmarks call Minestom methods that take a fastutil collection, which makes the dependency's presence on the compile classpath necessary and its version explicit here.

Why Minestom, fastutil and adventure-nbt are compileOnly

Across falco-anvil, falco-light and falco-instance, three dependencies are declared compileOnly rather than implementation:

compileOnly(libs.adventure.nbt)
compileOnly(libs.annotations)
compileOnly(libs.minestom)

Minestom itself is what a consumer of these libraries always already has on their classpath — a library that bundled its own copy would risk a classpath conflict with whichever Minestom version the consuming server actually runs. adventure-nbt and the JetBrains annotations follow the same logic: they are supplied transitively by Minestom (or are annotation-only, CLASS-retention artefacts that are never needed at runtime at all), so bundling them again would be redundant at best and a version clash at worst.

The practical consequence for consumers: anything that depends on falco-anvil, falco-light, or falco-instance must already have Minestom (and, indirectly, Adventure) on its own runtime classpath. That is true for essentially every project this library is meant to be used in, since none of them make sense without Minestom present.

falco-instance additionally marks fastutil compileOnly, for the same reason as the version catalog note above: the block entry maps of DynamicChunk are fastutil types, and copying a chunk has to touch them, but Minestom only supplies fastutil at runtime scope so falco-instance names it explicitly to have it during compilation.

Test source sets declare all of the same dependencies with testImplementation instead — tests run with a real classpath, so the compileOnly restriction that matters for the published jar does not apply there.

Clone this wiki locally