From Dependency Hell to Developer Zen: Why Quarkus Made Me Rethink My Build
How Quarkus’s curated extensions and BOMs put me back in control and helped me ditch the transitive chaos of traditional Java stacks.
We’ve all been there. You start a new Java project, add a few Spring starters, sprinkle in a library or two, and… boom. A dozen transitive dependencies sneak in through the back door. Suddenly, you’re troubleshooting a logging conflict or scratching your head over which version of Jackson you’re actually using.
This isn’t just annoying: It’s risky. Unwanted dependencies can inflate your container image, delay startup, introduce CVEs, and generally erode trust in your own stack.
Then I discovered Quarkus. And let’s just say, it felt like cleaning out a junk drawer I didn’t realize was overflowing. In this hands-on tutorial, we’ll explore how Quarkus simplifies and disciplines dependency management using its powerful extension system, curated platform BOMs, and developer-friendly tooling.
Whether you're migrating from Spring or just tired of dependency roulette, this guide will help you regain control.
Prerequisites
Make sure you have the following installed:
Java 17+
Maven 3.9+
Quarkus CLI (optional but recommended):
brew install quarkusio/tap/quarkus
You can follow along using the Quarkus CLI or plain Maven. Let’s jump in.
Step 1: Generate a Minimal Project
Let’s start with a fresh Quarkus application that includes just enough to serve a REST endpoint.
quarkus create app org.acme:dependency-demo \
--no-code --extension='rest-jackson'
cd dependency-demo
Take a peek at the generated pom.xml
. You’ll notice something immediately:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus.platform</groupId>
<artifactId>quarkus-bom</artifactId>
<version>...</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
This is the Quarkus Platform BOM, and it’s doing a ton of heavy lifting behind the scenes.
Why it matters:
Unlike adding a wildcard of Spring Boot starters and letting the transitive waterfall begin, Quarkus takes a different approach. You declare the extensions you want, and the platform BOM pins every single version. This gives you consistency across builds and total transparency.
Step 2: Explore the Lean Dependency Graph
Run the following Maven command to visualize your dependencies:
./mvnw dependency:tree -Dincludes=org.acme
Now compare that with:
./mvnw dependency:tree
You’ll notice that Quarkus pulls in just what you asked for. There’s no cascade of libraries unless they're explicitly required by an extension.
For example, using quarkus-rest-jackson
doesn’t suddenly pull in Spring Web, Jackson XML, and half of Apache Commons.
Quarkus has a strict extension model. If you didn’t ask for it, it’s not coming to the party.
Step 3: Add a Database Without the Usual Chaos
Let’s say you want to persist data with Panache and PostgreSQL. In Spring, you might start by adding spring-boot-starter-data-jpa
, postgresql
, and hope that you don’t end up with Hibernate Validator 6.x when your app expects 8.x.
Here’s how clean it looks in Quarkus:
quarkus extension add hibernate-orm-panache postgres
This updates your pom.xml
with:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
That’s it. The Quarkus BOM ensures these versions are guaranteed to work together.
No manual alignment, no unexpected transitive libraries, just a fast startup, Hibernate running with small memory overhead, and Panache giving you a slick API.
Step 4: Go Native, Stay Lean
One of the most dramatic effects of dependency bloat shows up when compiling to a native executable.
Let’s test that with:
./mvnw package -Pnative
The smaller your dependency graph, the faster and more reliable your native build. Quarkus’s extension system ensures that every extension is native-compatible and tested against the GraalVM compiler.
No need to guess if that random library from Maven Central will crash your native build: If it’s a Quarkus extension, it works.
Step 5: Compare Logs with --dry-run
Ever wonder what dependencies are actually triggered by an extension?
quarkus create --dry-run
This mode lets you inspect what Quarkus is going to do without actually building the app. You can review which extensions are installed, which build steps are triggered, and where the dependencies come from.
It’s like peeking under the hood without committing to the drive.
Bonus: Avoiding the “Log4j Surprise”
In the Spring ecosystem, it’s easy to accidentally include both Logback and Log4j through various starters. Quarkus avoids that entire category of problems by having opinionated, centralized logging through JBoss Logging and slf4j, with no ambiguous transitive logging implementations.
quarkus extension add quarkus-logging-logback # You won’t need this unless you *really* want it
Quarkus uses the JBoss Log Manager logging backend for publishing application and framework logs. Quarkus supports the JBoss Logging API and multiple other logging APIs, seamlessly integrated with JBoss Log Manager. Lean, production-ready options built right in.
Reflection: Why This Feels Different
With Quarkus:
I only add what I need.
I never have to override versions manually.
I don’t worry about dependency hell.
My native builds succeed without a fight.
My images are smaller and boot faster.
This isn’t just about being lean. It’s about trust. With Quarkus, I trust the platform to get it right and when I want to customize, the system is transparent and predictable.
Compare that to the occasional guessing game in Spring when trying to align different starters, override transitive dependencies, or debug clashing annotations.
Conclusion: Dependency Zen with Quarkus
Modern development demands more than convenience. It demands intentionality. Quarkus isn’t just a fast runtime, it’s a disciplined ecosystem that prioritizes clarity and control.
The curated BOMs, strict extension model, and native-first mindset give you peace of mind in production and speed during development.
If you’re tired of the dependency bloat, give Quarkus a shot. You might just find yourself enjoying pom.xml
again.
Because once you tame your dependencies, the next step is owning your ecosystem.