> Markdown version of [Single-module Projects](https://vaadin.com/docs/next/building-apps/architecture/project-structure/single-module). Section index: [llms.txt](https://vaadin.com/docs/next/building-apps/llms.txt)

# Single-Module Projects

A single-module project consists of a single directory, with a single POM file and a single source directory. During the build, Maven packages the module either into a self-contained executable JAR file, or into a WAR file.

Single-module projects are simple and easy to understand. They’re best suited for smaller applications, and ones that are maintained by small development teams. They’re also suitable for new projects, since it’s easy to migrate from a single-module project to a multi-module one — if the need arises.

> **Note:** Your architecture imposes constraints on how parts of your code can interact. In a single-module project, all of the code is in the same place. There are no technical safeguards to prevent breaking these constraints — intentionally or otherwise. The risk of this happening grows with the codebase or as the number of people involved increases. This can lead to the code becoming unmaintainable: known as a "Big Ball of Mud". When it seems this may be approaching, consider adding [ArchUnit](https://www.archunit.org/) tests to your project, or converting to a [multi-module](https://vaadin.com/docs/next/building-apps/architecture/project-structure/multi-module.md) project.

You can use various starters to create new single-module Vaadin projects. Or you can create a new project without starters, by using a basic Maven POM file and adding the necessary sections to it.

## <a id="spring-boot-starter-parent"></a>Spring Boot Starter Parent

For all Spring Boot projects, much of the configuration is imported through the `spring-boot-starter-parent`:

```xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>4.1.0</version> <!--(1)-->
    <relativePath/>
</parent>
```

1. You can check for the latest version on the [Maven Central Repository](https://central.sonatype.com/artifact/org.springframework.boot/spring-boot-starter-parent).

The parent imports all of the Spring Boot dependencies and configures the most common Maven plugins (e.g., the compiler) using sensible defaults.

## <a id="project-properties"></a>Project Properties

Declare all other dependency versions as project properties, like this:

```xml
<properties>
    <java.version>21</java.version> <!--(1)-->
    <vaadin.version>25.4.0-alpha1</vaadin.version> <!--(2)-->
</properties>
```

1. This property is used by `spring-boot-starter-parent` to configure the Java compiler plugin.

2. You can check for the latest version on the [Maven Central Repository](https://central.sonatype.com/artifact/com.vaadin/vaadin-bom).

Declaring the dependency versions as properties makes it easier to upgrade. It also helps to get an overview of which dependencies your application has — other than the Spring Boot dependencies.

## <a id="vaadin-dependencies"></a>Vaadin Dependencies

Like Spring Boot, Vaadin comes with its own set of dependencies. These are imported through a Bill of Materials (BOM) like this:

```xml
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-bom</artifactId>
            <version>${vaadin.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
```

Importing the BOM makes the dependencies known to your project. When you use them, you don’t have to declare their versions. To use the dependencies, add them to your project like so:

```xml
<dependencies>
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>com.vaadin</groupId>
        <artifactId>vaadin-dev</artifactId>
        <optional>true</optional> <!--(1)-->
    </dependency>
</dependencies>
```

1. The `vaadin-dev` dependency enables development tools such as the Vite dev server and live-reload. Marking it `<optional>true</optional>` ensures that `spring-boot-maven-plugin` excludes it from the production JAR.

The only dependency you need for building a simple Vaadin application is `vaadin-spring-boot-starter`. In a real application, you would also add dependencies for at least persistence and database access — and for running tests.

## <a id="maven-plugins"></a>Maven Plugins

Next, to build your project, you’ll need to add two more Maven plugins:

```xml
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>

        <plugin>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-maven-plugin</artifactId>
            <version>${vaadin.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>build-frontend</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
```

The `spring-boot-maven-plugin` does plenty, but for now think of it as the plugin that packages a project into a single, executable JAR file. For more information about this plugin, see the [Spring Boot documentation](https://docs.spring.io/spring-boot/maven-plugin).

The `vaadin-maven-plugin` takes care of building the frontend. The `build-frontend` goal installs frontend tools if needed, reviews all of the resources used by the application, generates missing source files, and compiles and bundles the frontend resources. For more information, see [Production Build](https://vaadin.com/docs/next/flow/production/production-build.md) and [Maven Configuration Properties](https://vaadin.com/docs/next/flow/configuration/maven.md).

## <a id="the-complete-pom"></a>The Complete POM

A fully configured POM file for a single-module Vaadin application looks like this:

pom.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example.application</groupId>
    <artifactId>application</artifactId>
    <name>application</name>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

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

    <properties>
        <java.version>21</java.version>
        <vaadin.version>25.4.0-alpha1</vaadin.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <version>${vaadin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-dev</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-maven-plugin</artifactId>
                <version>${vaadin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>build-frontend</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
```
