Vaadin Flow is a server-driven UI framework that can serve as an alternative to React or Angular, where the frontend exists as a separate codebase written in a different programming language, with a clear boundary for data management (AJAX). For admin UIs, where backend developers manage the interface without deep knowledge of frontend technologies, this approach simplifies the architecture and reduces the overall maintenance effort. I would like to share my experience of adopting this framework.
Context
We are specifically dealing with admin UIs, typically have fewer concurrent users but each may have long-running sessions. An example of admin ui is social media moderator room where target users of ui are employees of a company that usually have long sessions. Another major attribute of admin ui is a complex UI with rich business logic, often making it unclear how to split code between frontend and backend.
All of this allows us to:
- Manage the user's UI state on the backend since we can allocate resources for each user.
- Put functionality ahead of perfect UX, as interface users can be trained.
- Ignore initial loading time, as it is not critical for an admin UI.
- Keep UI-related code alongside the backend, since they are tightly coupled, and no other consumers rely on the same API.
We also prefer open-source solutions with free-to-use licenses, as they provide the flexibility to fix critical bugs when needed.
Solution
All of this leads us to consider backend-driven UI frameworks like Vaadin Flow, a Java framework for server-rendered UIs. The majority of UI configuration—both layout and behavior—will be written in Java, just like the backend code.
For UI pages Vaadin flow provides Routes that can interact directly with spring services without a controllers layer. All state from Vaadin flow route transfers to the user browser using Vaadin internals without extra boilerplates like ajax requests and react subjects.
For special cases when integration with 3rd party libraries are required there are bridge interfaces with react (details).
UI testing in the free version might be done using Microsoft Playwright or Selenium.
Architecture
Enterprise applications often share similar requirements, which are implemented using common building blocks. Since Vaadin is designed for admin UIs and has undergone multiple iterations, you can find well-documented features in its official documentation. While some advanced components are available only in the paid version, with experience and guidance (even from ChatGPT), you can build them yourself.
- Build (maven / gradle)
- Assemble to container (docker)
- Integration with beans management framework (Spring, Quarkus, JBoss CDI)
- Secure using SSO (Authz)
- Shared layout
- Display data grids (tables)
- Display forms with data
Build
Vaadin supports maven and gradle but documentation is well written only for maven. In some cases you may find bugs caused by gradle groovy to kotlin migration.
Containerisation
Vaadin offers a development mode with reduced build times and a production mode that compacts the JavaScript bundle and integrates user-defined components. It’s essential to test your production build to catch any potential build-related bugs early.
This topic covered by this guide (https://vaadin.com/docs/latest/flow/production/production-build )
Integration with beans management framework
Vaadin can be easily integrated with leading Java frameworks like Spring, Quarkus, and CDI. In the case of Spring, Vaadin routes can be treated as Spring components with a web session-like scope, meaning a bean is created per user session and retains state throughout user interactions. This scope is particularly intuitive for form management (covered in next sections).
Authz
While “SSO Kit” is a part of paid version you can rely on Spring authz that provides similar functionality. For example, you can delegate this task to Spring security with Keycloak.
spring.security.oauth2.client.registration.keycloak.client-id=${keycloak.client-id}
spring.security.oauth2.client.registration.keycloak.scope=openid,profile,email
spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.keycloak.redirect-uri=${app.protocol}://${app.host} /login/oauth2/code/{registrationId}
spring.security.oauth2.client.provider.keycloak.issuer-uri=${keycloak.issuer-url}
spring.security.oauth2.client.provider.keycloak.jwk-set-uri=${keycloak.base-url}/protocol/openid-connect/certs
Layouts
As a starting point for hands-on experience, you can use Vaadin Start, which provides an online UI designer and generates related code. Take a closer look at the generated code to better understand AppLayout, which serves as a top-level placeholder for other views, and an example of a user-defined route (view) that extends VerticalLayout or HorizontalLayout.
Your UI is primarily built using two key layout components: HorizontalLayout and VerticalLayout, both of which can contain other UI components or nested layouts.
Data grids
Vaadin calls it com.vaadin.flow.component.grid.Grid (https://vaadin.com/docs/latest/components/grid ). It contains sorting, filtering and lazy loading.
Forms
The primary integration layer is com.vaadin.flow.data.binder.Binder, which synchronizes Java Beans with the UI state. It also provides an API for validation using withValidator.
// example
var binder = new Binder<>(BusinessPerson.class);
TextField nameField = new TextField();
binder.bind(nameField, BusinessPerson::getName, BusinessPerson::setName);
This topic covered by https://vaadin.com/docs/latest/flow/binding-data
Bonus: long running tasks
You might encounter a situation where each user interaction with a Java service, such as one involving long blocking database interactions, also blocks the user interface. While this may not be a problem for short interactions, long-running tasks, like bulk imports or exports, should be offloaded to threads that are not dedicated to rendering the UI. This approach is like what is done in other rendering frameworks, such as Swing or AWT.
More details https://vaadin.com/docs/latest/building-apps/application-layer/background-jobs , https://vaadin.com/docs/latest/flow/advanced/long-running-tasks
Alternatives
Since Vaadin is Java-focused, its major benefits are best realized within that ecosystem. If you're using .NET, Blazor might be a better fit, while in the Python world, a lightweight alternative could be Streamlit.
Author is Mark Andreev, SWE
Top comments (11)
I found this tool really useful because my team know Java and can create well structured project with right class placement. At the same time when we need something special like block with sql highlight (something like highlightjs) we just requested help from JS team.
May be you can share sample project that will help others to onboard it faster?
I see some issues when we rely on this magic. It might be hard to debug issue that happens in the middle of this tech stack.
Since GWT days something changed. In 2025 we have mui for React that allow you to create simple admin ui without deep knowledge of frontend tech.
Be honest. Tell us about learning curve..
It might take some time to set up all the components, especially if you have a corporate proxy or a non-trivial CI/CD runner.
After that, development will be straightforward, with each subsequent page requiring less time.
I suggest to try Angular that look similar to Spring. The same dependency injection that Java Devs love :)
What do you think about classical approach with JQuery + Spring MVC?
Thank you, very informative.
What about Vaadin Hilla?
Is it fully free or something hidden in paid version?
And price are not transparent..