Course: Build a Web Application With Spring Boot and Vaadin Flow

This guide is a practical introduction to web application development with Spring Boot and Vaadin.

It covers the entire development process, from setup to deployment, following a step-by-step approach. You can replicate each section at your own pace as you follow along.

The content is suitable for anyone familiar with Java who wants to build a web application. To make sure your development experience is enjoyable and productive, you start right from the beginning with setting up your development environment.

What You Learn From This Tutorial

This guide teaches you how to build a functional, full-stack web application using modern Java. It focuses on real-world developer needs, without diving into theory or academics. Links to relevant further reading are provided for those who are interested.

The application is a customer relationship management (CRM) system for managing contacts. It features:

  • A login screen to restrict access.

  • A responsive layout with side navigation that works on desktop and mobile.

  • A database for persistent data storage.

  • A list view that can be sorted and filtered.

  • A form to edit and add contacts.

  • Data import from a REST API.

  • A dashboard view.

  • Cloud deployment.

  • Application installation on mobile and desktop.

Tools and Frameworks

This tutorial uses Vaadin and Spring Boot because they are both easy to learn and suitable for production use.

On the backend, the application uses Spring Boot. This eliminates most of the hassle of setting up and running a Spring-based application and lets you focus on your own code. The main features you’ll use are:

Don’t worry if you don’t know these terms, the tutorial covers each topic.

On the frontend, the application uses Vaadin Flow Vaadin Flow is an open-source Java web application framework that comes with:

  • A large library of UI components. Each component has a Java API and you can customize the look and feel.

  • A router for navigating between views.

  • A powerful data-binding system for forms and lists.

Why Use Vaadin Instead of Spring MVC and Thymeleaf, JSP or Freemarker?

Vaadin is an alternative to using Spring MVC and Thymeleaf, JSP or Freemarker when building web applications with Spring Boot.

The main advantage of Vaadin are:

  • Vaadin is designed for building interactive single-page apps (SPA). Spring MVC and templates are better suited for more static content.

  • Vaadin offers a Java component API, allowing you to build the entire application in Java.

  • Vaadin comes with a large library of customizable UI components.

  • Vaadin handles the communication between the server and the browser automatically, you don’t need to write any JavaScript to update content dynamically.

Why Use Vaadin Instead of REST and React or Angular?

Combining a Spring Boot based REST backend with a frontend framework like React or Angular is a popular way of building SPAs. Vaadin allows you to build similar application experiences with less effort.

Advantages of using Vaadin:

  • Faster development: you do not need to develop the backend and frontend separately.

  • You can write the entire application in type safe Java.

  • Vaadin comes with a large library of customizable UI components.

  • Vaadin handles the communication between the server and the browser automatically, you don’t need to write any JavaScript to update content dynamically.

  • More secure: the Vaadin application runs on the server and doesn’t expose application code or extra endpoints to the browser.

You can compare Vaadin, Angular, React, and Vue on the Framework Comparison page.

Source Code

You can find the full source code for this guide on GitHub.

Video Tutorials

You can find video tutorials of each chapter on the Vaadin YouTube Channel.

Download free e-book.
The complete guide is also available in an easy-to-follow PDF format.

export class RenderBanner extends HTMLElement {
  connectedCallback() {

  renderBanner() {
    let bannerWrapper = document.getElementById('tocBanner');

    if (bannerWrapper) {

    let tocEl = document.getElementById('toc');

    // Add an empty ToC div in case page doesn't have one.
    if (!tocEl) {
      const pageTitle = document.querySelector(
        'main > article > header[class^=PageHeader-module--pageHeader]'
      tocEl = document.createElement('div');

      pageTitle?.insertAdjacentElement('afterend', tocEl);

    // Prepare banner container
    bannerWrapper = document.createElement('div'); = 'tocBanner';

    // Banner elements
    const text = document.querySelector('.toc-banner-source-text')?.innerHTML;
    const link = document.querySelector('.toc-banner-source-link')?.textContent;

    const bannerHtml = `<div class='toc-banner'>
          <a href='${link}'>
            <div class="toc-banner--img"></div>
            <div class='toc-banner--content'>${text}</div>

    bannerWrapper.innerHTML = bannerHtml;

    // Add banner image
    const imgSource = document.querySelector('.toc-banner-source .image');
    const imgTarget = bannerWrapper.querySelector('.toc-banner--img');

    if (imgSource && imgTarget) {