Skip to content
Spring Boot sb core 3 min read

Starters

A starter is a curated set of dependencies you add as a single coordinate instead of hunting down every individual jar and matching its version. spring-boot-starter-web, for instance, brings Spring MVC, an embedded Tomcat, Jackson, and validation in one line. Starters are the front door to Spring Boot’s auto-configuration: adding one puts the right libraries on the classpath, and auto-config does the wiring.

What a starter actually is

A starter is mostly an empty jar — a pom.xml with no code — that declares transitive dependencies. Adding spring-boot-starter-web pulls in everything you need for a web application, transitively. Starters follow a naming convention: official ones are spring-boot-starter-*; third-party ones use their own prefix, like acme-spring-boot-starter.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Notice there is no <version>. That is the second half of the story: dependency management.

Dependency management and the BOM

Spring Boot publishes a BOM (Bill of Materials) named spring-boot-dependencies that pins compatible versions for hundreds of libraries. When your project inherits or imports it, you declare dependencies without versions and Spring Boot supplies a tested, consistent set — eliminating version conflicts between, say, Jackson and Spring.

The simplest way to get the BOM is to inherit from spring-boot-starter-parent:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.5.0</version>
    <relativePath/>
</parent>

The parent also configures the compiler for Java 17+, sets UTF-8 encoding, and pre-configures plugins like spring-boot-maven-plugin.

If your project already has its own parent, import the BOM in dependencyManagement instead:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.5.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Tip: To override a managed version (for example, to bump a single library), set the corresponding property the BOM defines — e.g. <jackson-bom.version>2.18.0</jackson-bom.version> — rather than pinning a <version> on the dependency itself. This keeps the rest of the dependency set coherent.

Common starters

StarterWhat it brings
spring-boot-starter-webSpring MVC, embedded Tomcat, Jackson JSON, validation — build REST APIs and MVC apps
spring-boot-starter-data-jpaSpring Data JPA, Hibernate, JDBC, transaction management
spring-boot-starter-securitySpring Security: filter chain, authentication, authorization
spring-boot-starter-validationJakarta Bean Validation API + Hibernate Validator
spring-boot-starter-testJUnit 5, Mockito, AssertJ, Spring Test, JSONassert (test scope)
spring-boot-starter-actuatorProduction endpoints: health, metrics, info, env over HTTP/JMX

A minimal REST + persistence service typically needs just a few:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Note: Some starters are “technical” rather than feature-based. spring-boot-starter is the core starter (used by others); spring-boot-starter-logging provides the default Logback setup; and you swap spring-boot-starter-tomcat for spring-boot-starter-jetty or -undertow to change the embedded server.

Authoring a custom starter

When you build a reusable library — say, an internal client for a shared service — you can ship it as a starter so consumers get it working with one dependency. The convention splits the work into two modules:

  1. An autoconfigure module (acme-spring-boot-autoconfigure) containing the @AutoConfiguration classes, @ConfigurationProperties, and the AutoConfiguration.imports file.
  2. A thin starter module (acme-spring-boot-starter) with no code that depends on the autoconfigure module plus any required libraries.

Warning: Naming matters. Use acme-spring-boot-starter, not spring-boot-starter-acme — the spring-boot-starter- prefix is reserved for starters maintained by the Spring Boot team. Mixing it up causes confusion about provenance and support.

The autoconfigure module registers its config class:

# acme-spring-boot-autoconfigure/src/main/resources/
#   META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.acme.autoconfigure.AcmeClientAutoConfiguration
@AutoConfiguration
@ConditionalOnClass(AcmeClient.class)
@EnableConfigurationProperties(AcmeProperties.class)
public class AcmeClientAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public AcmeClient acmeClient(AcmeProperties props) {
        return new AcmeClient(props.baseUrl(), props.apiKey());
    }
}

The starter module is just dependencies:

<project>
    <artifactId>acme-spring-boot-starter</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.acme</groupId>
            <artifactId>acme-spring-boot-autoconfigure</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.acme</groupId>
            <artifactId>acme-client</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
</project>

Consumers then add a single dependency, and the conditional beans in your autoconfigure module wire themselves up — backing off via @ConditionalOnMissingBean if the consumer defines their own.

Best Practices

  • Inherit spring-boot-starter-parent for new projects; import spring-boot-dependencies when you already have a parent.
  • Declare Spring-managed dependencies without versions and let the BOM decide.
  • Override a managed version through the documented BOM property, not a hard-coded <version>.
  • Pick the smallest set of starters that covers your features; remove ones you no longer use to keep the classpath lean.
  • For custom starters, follow the two-module split and the *-spring-boot-starter naming convention.
Last updated June 13, 2026
Was this helpful?