Skip to main content

Best Spring Boot Boilerplates for Java Developers 2026

·StarterPick Team
Share:

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

StarterPriceAuthDBFrontendBest For
JHipsterFreeFull (Keycloak/OAuth2)MultipleReact/Vue/AngularComplete app generation
spring-initializrFreeOptionalMultipleOfficial scaffold
spring-boot-jwtFreeJWTPostgreSQLREST API with auth
BootifyFree/€9-79FullMultipleNo-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 →

The SaaS Boilerplate Matrix (Free PDF)

20+ SaaS starters compared: pricing, tech stack, auth, payments, and what you actually ship with. Updated monthly. Used by 150+ founders.

Join 150+ SaaS founders. Unsubscribe in one click.