Beyond Spring: Unlock Modern Java Development with Quarkus
What Spring Didn’t Teach You: Becoming a Modern Java Developer with Quarkus
Hello guys, as a Java developer we all have used Spring and Spring Boot and can vouch how much it help by standardizing the server side Java development but is Spring Boot still the best framework?
Well, before we can make a decision we also need to find out about modern Java framework like Quarkus and what they offer?
In the past, I have shared about Spring boot resources and concepts like @Component vs @Bean, @GettingMapping vs @PostMapping and Spring Boot interview questions.
Today I am excited to partner with
, a Java champion with more than 20 years of experience who I have known for quite long time on Twitter and he has now also joined so we are going to see more high-quality Java content right here.In this post, you will learn beyond Spring, how you can use frameworks like Quarkus to become a modern Java developer.
Now, over to Markus to take you through the article.
Spring has been a faithful companion to Java developers for two decades. But frameworks, like developers, need to evolve.
Today’s cloud-native world values startup time, memory efficiency, predictable builds, and dev-friendly tooling over general-purpose flexibility.
This is where Quarkus comes in: a modern Java stack built with these priorities in mind.
This isn’t just a feature-by-feature comparison. This is about what Spring never forced you to think about — and why embracing Quarkus can make you a better, more modern developer.
Spring prioritizes abstraction. Quarkus makes the cost of abstraction visible.
Spring famously made Java "enterprise-ready" by abstracting away infrastructure concerns. But with that power came hidden complexity: runtime classpath scanning, reflective bean instantiation, and unpredictable boot sequences.
Quarkus flips the model. It does as much as possible at build time, not runtime. That means faster boot, lower memory, and fewer surprises.
Spring-style bean registration:
@Service
public class GreetingService {
public String hello() {
return "Hello from Spring!";
}
}
Quarkus equivalent:
@ApplicationScoped
public class GreetingService {
public String hello() {
return "Hello from Quarkus!";
}
}
At first glance, these look the same. But Quarkus turns this into a static build-time graph, using Jandex indexing and bytecode analysis. Spring waits until runtime, costing you boot time and reflection overhead.
With Quarkus, you’re not just writing DI-friendly code — you’re thinking about the life cycle of your application.
You were trained to run apps. Quarkus trains you to iterate.
One of the most powerful features of Quarkus is quarkus:dev
. It's not a plugin, it's a philosophy: shorten the feedback loop.
Change code
Save file
Quarkus reloads instantly
With Spring, you’re likely restarting the app or using brittle hot-swap tools. Over time, that friction shapes your behavior: fewer experiments, slower iterations.
With Quarkus, the inner loop is so fast that refactoring and testing become second nature.
Configuration as code! Not magic or mystery
Spring’s @Value
injection is easy to start with, but as projects grow, it becomes harder to understand where a value comes from. Spring’s property resolution can involve multiple layers (YAML merging, profile activation, environment variables), and debugging the effective value often feels like detective work.
Quarkus solves this cleanly:
Strong typing via
@ConfigProperty
, not only string substitution.Profiles (like
dev
,test
,prod
) are first-class and intuitive.Live reload during development means you can update configuration without restarting.
Example – application.properties
:
server.timeout=5s
server.port=8080
And in Java:
import java.time.Duration;
import java.util.Optional;
@ConfigProperty(name = "server.timeout")
Duration timeout;
@ConfigProperty(name = "server.port")
Optional<Integer> port;
In this example, timeout
is automatically parsed into a Duration
, and port
is an Optional<Integer>
. No manual parsing, no boilerplate.
Need a different timeout for tests? Create an application-test.properties
, override server.timeout=1s
, and Quarkus will automatically pick it up — no need to navigate Spring’s complex property source precedence rules.
In Quarkus, configuration is explicit, type-safe, and predictable.
Modern REST without extra runtime baggage
Spring Boot uses Spring MVC or WebFlux — both powerful, but heavy in different ways.
Quarkus uses Quarkus REST (based on Jakarta REST) with first-class support for both blocking and non-blocking I/O — without requiring you to choose a different programming model.
Simple REST endpoint in Quarkus:
@Path("/hello")
public class HelloResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello from Quarkus!";
}
}
Want to go reactive later? Just return a Uni<String>
instead of a String
.
@GET
@Produces(MediaType.TEXT_PLAIN)
public Uni<String> helloAsync() {
return Uni.createFrom().item("Hello reactive world!");
}
Spring taught you to structure for the JVM. Quarkus teaches you to structure for containers.
Spring Boot apps often assume a monolithic runtime model: auto-scanning, runtime wireups, fat JARs.
Quarkus assumes the opposite: fast startup, small memory footprint, predictable behavior in containers.
Multi-stage Dockerfile for Quarkus app:
FROM quay.io/quarkus/quarkus-micro-image:latest
COPY target/*-runner /work/application
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
No tuning required. You get a fast-starting binary or JVM-based app that behaves consistently: even under orchestration.
From Annotations to Actions — Thinking Beyond Decorators
Spring's annotation model works. Until it doesn't. It's common to see classes overloaded with annotations, some of which conflict or depend on runtime context. Quarkus encourages explicitness.
You still use annotations, but the behavior is clear and lifecycle-friendly.
@Scheduled(every = "10s")
void doPeriodicTask() {
System.out.println("Running every 10 seconds");
}
No surprises, no guessing how beans get initialized. It just works — at build time.
Modern Java is more than syntax — it’s about assumptions
You might write Java 17 or 21. But are you writing for the future of Java?
Quarkus encourages:
Records for DTOs
CDI scopes that map better to container lifecycles
Panache for simpler Hibernate models
Reactive APIs where appropriate, without forcing your entire stack to be reactive
Panache example:
@Entity
public class Person extends PanacheEntity {
public String name;
public int age;
}
Query it like this:
Person.find("name", "Alice").firstResult();
Simple. Expressive. And efficient.
Native images are an upgrade — not a requirement
This is where many Spring developers get nervous: "Do I have to use GraalVM to use Quarkus?"
The answer: Absolutely not.
Quarkus runs exceptionally well on the JVM, with fast startup, low memory, and predictable behavior. Most teams adopt Quarkus without touching native builds.
But when you’re ready for cold starts, functions, or edge deployments, Quarkus makes the native path smoother than anything else in Java.
./mvnw package -Dnative
You’ll need GraalVM or Mandrel, but it’s fully integrated. You don’t rewrite your app. You optimize it.
Final thoughts: Spring got you here. Quarkus takes you forward.
Spring gave you the building blocks. But today’s cloud-native Java world is about build-time optimization, container-native behavior, and fast iteration cycles.
Quarkus isn’t just a faster Spring. It’s a different way of thinking about what Java can be.
Want dev joy?
Want control over startup time and memory?
Want to use Java for AI, serverless, or microservices?
Try it now
You don’t have to start with migrating your monolith. Start small:
mvn io.quarkus.platform:quarkus-maven-plugin:3.9.3:create \
-DprojectGroupId=com.example \
-DprojectArtifactId=hello-quarkus \
-DclassName="com.example.HelloResource" \
-Dpath="/hello"
Then run:
cd hello-quarkus
./mvnw quarkus:dev
Visit http://localhost:8080/hello and see how it feels to develop with the Java platform of the future.
Ready to go further?
Explore the Quarkus getting started guide, check out Dev Services, or try building your first app with Panache and REST.
You're not just learning a new framework — you're learning how modern Java works.
And, if you like this article then don’t forget to subscribe Markus’ newsletter
Other Java and System Design Articles you may like