Best Spring Boot Boilerplates for Java Developers 2026
TL;DR
- JHipster is the right choice for most enterprise Spring Boot projects — entity generation, full auth (JWT or Keycloak/OAuth2), Docker, and Kubernetes config in one generator.
- Spring Initializr is the correct starting point when you want a clean, unconstrained foundation and have a team with strong Spring opinions — it is not a boilerplate, it's a dependency scaffold.
- Bootify fills the gap for teams that want generated Spring Boot code without JHipster's full-stack opinions — useful when your frontend is already built separately.
- Java 21 virtual threads (Project Loom) change the Spring Boot performance story in 2026 — blocking code is no longer a performance tax, and the reactive programming tradeoffs shift significantly.
- GraalVM native image is production-viable in Spring Boot 3.x — if cold start time matters (serverless, Kubernetes rapid scaling), native compilation is now a real option not just a research project.
Key Takeaways
Spring Boot remains the dominant Java web framework in enterprise contexts, and in 2026 it has taken a significant leap forward with Spring Boot 3.x running on Spring Framework 6 and Java 21. The combination of virtual threads from Project Loom and improved GraalVM native image support addresses the two most common complaints about the Spring ecosystem: thread-per-request model inefficiency and slow startup time.
For developers evaluating Spring Boot boilerplates, the landscape is more mature and more opinionated than JavaScript equivalents. JHipster has 10+ years of development behind it and produces genuinely production-ready applications. Spring Initializr is the official scaffold but deliberately minimal. Bootify bridges the gap with a GUI-driven generator for teams that want generated code but not JHipster's specific choices.
The context that matters most for boilerplate selection: Spring Boot is rarely the right choice for greenfield startups prioritizing velocity, but it's often the only viable choice for enterprise organizations with Java-first engineering cultures, existing Spring infrastructure, compliance requirements that favor Java ecosystem tooling, or integration requirements with legacy Java-based enterprise systems (LDAP, JMS, SOAP services). Within that context, choosing the right boilerplate saves weeks of scaffolding work.
Spring Boot in 2026
Spring Boot 3.x (the current line as of 2026) requires Java 17 minimum and is optimized for Java 21. The headline features that change the Spring Boot development and deployment story:
Java 21 Virtual Threads (Project Loom)
Virtual threads are lightweight threads managed by the JVM, analogous to goroutines in Go or green threads in other runtimes. The Spring Boot implication: enabling virtual threads on Java 21 removes the performance cost of the traditional thread-per-request model without requiring reactive programming.
Before Loom, high-concurrency Spring Boot applications had two options: scale by increasing the thread pool (memory-intensive — each OS thread uses ~1MB stack) or adopt Spring WebFlux with Project Reactor (reactive, non-blocking, but significantly more complex to write and debug). Virtual threads give you the simplicity of blocking code with the scalability of non-blocking — you write synchronous code, the JVM schedules it on virtual threads with near-zero overhead.
Enabling virtual threads in Spring Boot 3.x:
# application.yml
spring:
threads:
virtual:
enabled: true
That's the entire configuration change. With this enabled, every Tomcat request handler and @Async task runs on a virtual thread. Throughput under high concurrency improves dramatically for I/O-bound workloads, and reactive programming becomes a specialized tool rather than a scalability requirement.
GraalVM Native Image
Spring Boot 3.x includes first-class support for compiling to GraalVM native images — standalone executables that include the JVM, your application code, and all dependencies, but start in milliseconds rather than seconds.
Native image trade-offs in 2026: startup time drops from 2–10 seconds (JVM) to 50–200 milliseconds (native). Memory usage is lower (no JVM overhead). Throughput at steady state is similar or slightly lower than JVM with JIT compilation (GraalVM's AOT compiler is good but can't match JIT's runtime optimization). Build time increases significantly — a native image build takes 3–10 minutes compared to 30 seconds for a standard JAR build.
The practical use cases where native image matters: AWS Lambda functions where cold start time directly affects user experience, Kubernetes pods that need to scale from zero quickly, CLI tools distributed as binaries. For long-running server applications with heavy concurrent load, JVM with JIT is still faster at steady state.
Quick Comparison
| Starter | Price | Auth | DB | Frontend | Best For |
|---|---|---|---|---|---|
| JHipster | Free | Full (Keycloak/OAuth2) | Multiple | React/Vue/Angular | Complete app generation |
| spring-initializr | Free | Optional | Multiple | ❌ | Official scaffold |
| spring-boot-jwt | Free | JWT | PostgreSQL | ❌ | REST API with auth |
| Bootify | Free/€9-79 | Full | Multiple | ❌ | No-code Spring generation |
The Starters
JHipster — Best Complete Generator
Price: Free | Creator: JHipster team
The gold standard for Spring Boot application generation. Generate a complete Spring Boot + React/Vue/Angular/Svelte application with JWT or OAuth2/OIDC auth, PostgreSQL/MySQL/MongoDB, Docker, Kubernetes, and CI/CD configuration.
npm install -g generator-jhipster
mkdir myapp && cd myapp
jhipster
# ✔ Application type: Monolithic / Microservices
# ✔ Authentication: JWT / OAuth2
# ✔ Database: PostgreSQL / MySQL / MongoDB
# ✔ Frontend: React / Vue / Angular
JHipster's entity generator creates complete CRUD endpoints, frontend views, and database migrations from a domain model — dramatically reducing boilerplate.
Choose if: You're building a standard enterprise Spring Boot app and want everything scaffolded.
JHipster Entity Generation in Depth
The jhipster entity command (or the JDL language for defining multiple entities at once) is JHipster's most powerful feature. Define your domain model in JDL (JHipster Domain Language), run the generator, and get: JPA entity classes, Spring Data repository interfaces, service layer with transaction management, REST controller with pagination and filtering, DTO classes with MapStruct mappers, frontend CRUD views with form validation, Liquibase migration scripts, and test classes for each layer.
// domain.jdl — JHipster Domain Language
entity Product {
name String required
description String
price BigDecimal required min(0)
stock Integer
createdAt Instant
}
entity Order {
status OrderStatus required
totalAmount BigDecimal
createdAt Instant required
}
enum OrderStatus {
PENDING, CONFIRMED, SHIPPED, DELIVERED, CANCELLED
}
relationship ManyToOne {
Order{customer(email)} to User
}
relationship ManyToMany {
Order{products} to Product{orders}
}
Running jhipster jdl domain.jdl generates all the code for both entities, the enum, the relationship, and all test stubs. For an experienced developer, this saves 2–4 hours of boilerplate per entity.
JHipster also generates Kubernetes deployment manifests for the application and its dependencies:
# Generated by JHipster — kubernetes/myapp-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
spec:
containers:
- name: myapp
image: myapp:latest
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: prod,k8s
livenessProbe:
httpGet:
path: /management/health/liveness
port: 8080
readinessProbe:
httpGet:
path: /management/health/readiness
port: 8080
Spring Initializr — Official Scaffold
Price: Free | Creator: Pivotal/VMware
The official Spring project generator at start.spring.io. Select Spring Boot version, build tool (Maven/Gradle), Java version, and dependencies. No auth, no frontend — a clean Spring Boot foundation.
Choose if: You want to configure Spring Boot from scratch with specific dependencies.
Spring Initializr is the right starting point when JHipster's choices (its ORM patterns, its frontend framework, its testing setup) don't match your team's requirements. It produces a minimal but valid Spring Boot project with correct dependency management, a sensible directory structure, and a passing health check — nothing more.
Bootify — Best No-Code Generator
Price: Free / €9-79 | Creator: Bootify
Web-based Spring Boot generator with a UI. Define your entities, relationships, and configuration — Bootify generates a complete Spring Boot project with OpenAPI docs, Thymeleaf or REST API, and proper layered architecture.
Choose if: Your team wants a visual way to generate Spring Boot projects without learning JHipster's conventions.
Bootify is particularly useful for teams building API-only backends (no frontend generation needed) who want a visual entity designer and don't want to write the boilerplate layer themselves. The paid tiers add features like Spring Security configuration, testing setup, and Docker support.
Spring PetClinic — Reference Architecture
Spring PetClinic (github.com/spring-projects/spring-petclinic) is not a production boilerplate but a reference application maintained by the Spring team to demonstrate Spring Boot best practices. It shows correct JPA entity modeling, Spring Data repository patterns, service layer design, Thymeleaf templating, and testing with @DataJpaTest and @WebMvcTest. When evaluating how to structure a Spring Boot application, PetClinic is the authoritative reference for the Spring team's own opinions.
Spring Boot Architecture
Spring Boot's standard layered architecture:
src/main/java/com/myapp/
├── config/ # Spring configuration beans
├── domain/ # JPA entities
├── repository/ # Spring Data repositories
├── service/ # Business logic
├── web/rest/ # REST controllers
│ └── dto/ # Data Transfer Objects
└── security/ # Spring Security config
// Standard Spring Boot REST endpoint
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserResource {
private final UserService userService;
@GetMapping
public ResponseEntity<List<UserDTO>> getAllUsers(Pageable pageable) {
return ResponseEntity.ok(userService.findAll(pageable));
}
@PostMapping
public ResponseEntity<UserDTO> createUser(@Valid @RequestBody UserCreateDTO dto) {
return ResponseEntity.created(URI.create("/api/users/"))
.body(userService.create(dto));
}
}
Spring Security Configuration
Spring Security is the most powerful and most complex part of the Spring ecosystem. Getting the configuration right from the start prevents security regressions later.
JWT Authentication
For stateless REST APIs, JWT is the standard approach. Spring Security 6.x (included in Spring Boot 3.x) has a clean OAuth2 resource server configuration for JWT:
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(s -> s.sessionCreationPolicy(STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**", "/actuator/health").permitAll()
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2
.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthConverter()))
)
.build();
}
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withSecretKey(getSecretKey()).build();
}
}
Method security with @EnableMethodSecurity lets you add authorization at the service layer rather than only in the security filter chain:
@Service
public class DocumentService {
@PreAuthorize("hasRole('ADMIN') or @documentSecurity.isOwner(#documentId, authentication)")
public Document getDocument(String documentId) {
return documentRepository.findById(documentId).orElseThrow();
}
}
OAuth2 with Keycloak
For enterprise applications requiring SSO, Keycloak is the standard self-hosted identity provider for the Spring ecosystem. JHipster generates Keycloak configuration out of the box. The Spring Boot configuration for a Keycloak-backed OAuth2 resource server:
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:9080/realms/myapp
jwk-set-uri: http://localhost:9080/realms/myapp/protocol/openid-connect/certs
The critical CSRF note for Spring Boot 3.x: CSRF protection is enabled by default for form-based applications but should be disabled for stateless REST APIs (as shown in the SecurityConfig above). Enabling CSRF on a stateless JWT API causes confusing 403 errors on POST/PUT requests — verify your CSRF configuration explicitly.
JPA and Database
Spring Data JPA is the standard ORM layer in Spring Boot applications. Entity relationships, query performance, and database migrations are the areas where most teams run into problems at scale.
Entity Relationships and N+1 Queries
The most common JPA performance issue: the N+1 query problem. When a parent entity has a @OneToMany relationship and you load N parents, JPA issues N+1 database queries by default — one for the parents list plus one for each parent's children collection.
The fix: use JOIN FETCH in JPQL queries or Spring Data's @EntityGraph to eager-load relationships in a single query when you know you'll need them:
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
// JOIN FETCH prevents N+1 when loading order line items
@Query("SELECT o FROM Order o JOIN FETCH o.lineItems WHERE o.customer.id = :customerId")
List<Order> findByCustomerIdWithItems(Long customerId);
// @EntityGraph alternative — cleaner for simple cases
@EntityGraph(attributePaths = {"lineItems", "lineItems.product"})
List<Order> findByStatus(OrderStatus status);
}
Database Migrations with Flyway
Liquibase is JHipster's default; Flyway is the alternative favored by many teams for its simplicity. Both manage versioned database schema changes. Flyway migrations are SQL files in src/main/resources/db/migration:
-- V1__create_users.sql
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- V2__add_user_roles.sql
CREATE TABLE user_roles (
user_id BIGINT REFERENCES users(id),
role VARCHAR(50) NOT NULL,
PRIMARY KEY (user_id, role)
);
Flyway applies migrations in version order on application startup, tracks applied migrations in a flyway_schema_history table, and fails startup if a migration that was previously applied has been modified — preventing the subtle bug of changing a migration after it's been applied in production.
Testing Strategy
Spring Boot has the most comprehensive testing support of any Java framework. The testing annotations define which parts of the application context to load, allowing fast, focused tests at each layer.
@SpringBootTest loads the full application context — use for integration tests that need the whole application running, but accept the slower startup cost. @DataJpaTest loads only the JPA layer (entities, repositories, datasource) — fast and focused for testing database queries. @WebMvcTest loads only the web layer (controllers, security, serialization) with services mocked — fast for testing HTTP endpoints without a database.
@DataJpaTest
class OrderRepositoryTest {
@Autowired
private OrderRepository orderRepository;
@Autowired
private TestEntityManager entityManager;
@Test
void findByCustomerId_returnsOnlyCustomerOrders() {
// Arrange
Customer customer = entityManager.persistAndFlush(new Customer("test@example.com"));
Order order1 = entityManager.persistAndFlush(new Order(customer, OrderStatus.PENDING));
Order order2 = entityManager.persistAndFlush(new Order(customer, OrderStatus.CONFIRMED));
// Act
List<Order> orders = orderRepository.findByCustomerId(customer.getId());
// Assert
assertThat(orders).hasSize(2);
assertThat(orders).extracting(Order::getStatus)
.containsExactlyInAnyOrder(OrderStatus.PENDING, OrderStatus.CONFIRMED);
}
}
For integration tests requiring a real database without connecting to a shared test database, Testcontainers spins up a real PostgreSQL container:
@SpringBootTest
@Testcontainers
class OrderServiceIntegrationTest {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15")
.withDatabaseName("testdb")
.withUsername("test")
.withPassword("test");
@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
}
@Autowired
private OrderService orderService;
@Test
void createOrder_persistsCorrectly() {
// Full integration test with real PostgreSQL
}
}
Testcontainers tests are slower than @DataJpaTest (container startup adds 5–15 seconds) but catch infrastructure-specific bugs that H2 in-memory tests miss — particularly around PostgreSQL-specific SQL features and constraint behavior.
Containerization and Deployment
Spring Boot's deployment story has improved significantly with layered JAR support and Buildpacks.
# Multi-stage Docker build for Spring Boot
FROM eclipse-temurin:21-jdk-alpine AS build
WORKDIR /app
COPY mvnw pom.xml ./
COPY .mvn .mvn
RUN ./mvnw dependency:resolve
COPY src src
RUN ./mvnw package -DskipTests
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Spring Boot's layered JARs (enabled by default in Boot 3.x) split the JAR into layers (dependencies, Spring Boot loader, snapshot dependencies, application code) that map to Docker layers. This means Docker only rebuilds the application code layer when you change your code — dependencies are cached. Build time for incremental changes drops from 60–90 seconds to 5–10 seconds.
For Kubernetes, JHipster generates Helm charts and raw Kubernetes manifests including Horizontal Pod Autoscaler configuration:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Spring Boot Actuator's /actuator/health/liveness and /actuator/health/readiness endpoints are Kubernetes-native probes — the application reports when it's ready to receive traffic and when it should be restarted. This is a production differentiator over simpler frameworks that don't distinguish between liveness (is the process alive?) and readiness (is the process ready to serve requests?).
Spring Boot vs Alternatives
The honest comparison for teams choosing between Spring Boot, Quarkus, and Micronaut.
Quarkus is Red Hat's Java microservices framework designed for GraalVM native image from the start. It has faster native image builds than Spring Boot (Quarkus optimizes for compile time, Boot optimizes for runtime). If native image is the primary deployment target, Quarkus has a more mature native experience. Quarkus also uses standard CDI and MicroProfile APIs rather than Spring's proprietary annotations — more portable across JVM frameworks.
Micronaut takes a compile-time dependency injection approach, eliminating reflection-based startup overhead. It starts faster than Spring Boot on JVM (without native image) and has lower memory usage. Micronaut is a good choice for teams building many small microservices where per-instance memory cost matters.
Spring Boot's advantages over both: far larger ecosystem, significantly more third-party integrations, the Spring Security framework (widely considered the most complete security library in the Java ecosystem), superior tooling support (IntelliJ IDEA Spring plugin, Spring Boot DevTools, Spring Initializr), and the largest community with the most Stack Overflow answers and tutorials. The ecosystem advantage compounds for teams building complex applications with unusual integration requirements.
The practical recommendation: Spring Boot is the default for enterprise Java applications unless you have specific reasons to prefer alternatives. Quarkus if native image is your primary deployment target. Micronaut if you're building many small services and JVM startup time and memory matter at scale.
When Spring Boot Makes Sense
Spring Boot is the right choice when:
- Your team is Java/Kotlin-first
- Enterprise integration (LDAP, SSO, legacy systems) is required
- Compliance requirements mandate Java (many financial/healthcare organizations)
- You need Spring Security's battle-tested security framework
- Horizontal scaling with microservices is planned from day one
Consider alternatives for:
- Startups prioritizing developer velocity (Spring Boot's verbosity slows prototyping vs Django/Rails)
- Small teams without Java expertise
- Projects where 200ms+ startup time is unacceptable (GraalVM native solves this but adds complexity)
For the broader boilerplate landscape beyond Java, the StarterPick boilerplate directory has comparisons across languages and frameworks. If you're evaluating Go as an alternative for high-throughput microservices, see best Go web boilerplates in 2026. And for the widest open source SaaS boilerplate comparison, see best open source SaaS boilerplates.
See also: best Django boilerplates 2026 for the Python counterpart to this guide — useful if your team is weighing Java vs Python for backend services. For JavaScript-based alternatives, our best SaaS boilerplates guide covers Next.js-based starters that pair with a Java or Python API backend.
Methodology
This article reflects direct evaluation of JHipster, Spring Initializr, Bootify, and Spring PetClinic as starting points for Spring Boot applications, including hands-on project generation and code review. Spring Boot 3.x and Java 21 feature coverage is based on the Spring Boot 3.3 release documentation and the Project Loom virtual thread documentation. Performance comparisons between Spring Boot, Quarkus, and Micronaut are based on published community benchmarks (TechEmpower, Renaissance benchmark suite) and should be treated as directional. All framework recommendations reflect the state of the ecosystem as of early 2026.
Check out this boilerplate
View JHipsteron StarterPick →