Vaadin: Java Web UI Without JavaScript?
I saw a Reddit post from a backend developer: 8 years of Spring experience, zero frontend knowledge, and the goal of building and deploying a web application. The comments were unanimous: “Try Vaadin.”
This struck a nerve. As a Java developer, I’ve faced the same dilemma. You’re comfortable with Spring, JPA, and the Java ecosystem. But then you need a web UI, and suddenly you’re looking at JavaScript, TypeScript, React, Angular, npm, webpack, and a whole new learning curve you don’t have time for.
Let me share what I discovered about Vaadin and how it solves this problem.
The Problem: Frontend Complexity for Java Developers
Modern web development expects you to know multiple languages and ecosystems. Here’s what you typically need:
- JavaScript or TypeScript
- Frontend framework (React, Angular, Vue)
- Build tools (Webpack, Vite)
- Package manager (npm, yarn, pnpm)
- CSS framework (Tailwind, Bootstrap)
- State management (Redux, Context API)
That’s a massive investment just to build a CRUD interface for your Spring Boot application.
The Solution: Server-Side UI with Java
Vaadin takes a different approach. You write your UI in Java, and Vaadin handles the rest. Here’s the basic idea:
Java Code → Vaadin Framework → Generated JavaScript → Browser ← Event Handling ← ←You create UI components in Java, handle events in Java, and Vaadin synchronizes everything with the browser automatically. No JavaScript required (though you can add it if you need to).
Getting Started with Spring Boot
Let me show you how simple it is. Here’s a complete Vaadin application with Spring Boot:
@SpringBootApplicationpublic class MyApp extends SpringBootServletInitializer {
@Override protected SpringApplicationBuilder configure(SpringApplicationBuilder app) { return app.sources(MyApp.class); }
public static void main(String[] args) { SpringApplication.run(MyApp.class, args); }}@Route("")public class AppView extends VerticalLayout {
public AppView() { // Create UI components in Java TextField nameField = new TextField("Name"); Button submitButton = new Button("Submit");
// Add layout and styling setSizeFull(); setAlignItems(Alignment.CENTER);
// Handle events in Java submitButton.addClickListener(e -> { String name = nameField.getValue(); Notification.show("Hello, " + name + "!"); });
// Add components to layout add( new H1("Vaadin Demo"), nameField, submitButton ); }}That’s it. No HTML, no JavaScript, no build configuration. Just Java.
Building a Data Grid with Spring Data
Let’s see a more realistic example: a user management page with a data grid.
@Route("users")public class UserView extends VerticalLayout {
private Grid<User> grid = new Grid<>(User.class); private UserRepository repository;
public UserView(UserRepository repository) { this.repository = repository;
grid.setColumns("id", "name", "email"); grid.setSizeFull();
Button addNew = new Button("Add User", e -> openEditor());
// Layout HorizontalLayout toolbar = new HorizontalLayout(addNew); toolbar.setWidthFull(); toolbar.setJustifyContentMode(JustifyContentMode.END);
add(toolbar, grid); setSizeFull();
updateList(); }
private void updateList() { grid.setItems(repository.findAll()); }
private void openEditor() { // Open dialog in Java UserEditor editor = new UserEditor(repository); editor.addSaveListener(this::updateList); editor.open(); }}public interface UserRepository extends JpaRepository<User, Long> {}The grid automatically handles sorting, filtering, and pagination. You just provide the data.
Form Binding and Validation
Vaadin’s Binder class makes form handling straightforward:
public class UserForm extends VerticalLayout {
private Binder<User> binder = new Binder<>(User.class);
public UserForm(User user) { TextField name = new TextField("Name"); EmailField email = new EmailField("Email"); NumberField age = new NumberField("Age");
// Bind fields to bean binder.forField(name) .asRequired("Name is required") .bind(User::getName, User::setName);
binder.forField(email) .asRequired("Email is required") .bind(User::getEmail, User::setEmail);
binder.forField(age) .asRequired("Age is required") .bind(User::getAge, User::setAge);
binder.readBean(user);
Button save = new Button("Save"); save.addClickListener(e -> { if (binder.writeBeanIfValid(user)) { // Save logic Notification.show("User saved!"); } });
add(name, email, age, save); }}Why This Matters for Java Developers
Stay in the Java Ecosystem
- Use Spring Boot for backend logic
- Type safety throughout the stack
- Familiar build tools (Maven/Gradle)
- Single JAR deployment
Faster Development
- No context switching between languages
- Unified codebase
- Simpler deployment
- Faster iteration cycles
Modern UIs
- Material Design themes
- Responsive layouts
- Accessible components
- Mobile-ready out of the box
When Vaadin Shines
Vaadin is ideal for:
- Business applications (admin panels, CRUD apps, dashboards)
- Internal tools
- Rapid prototyping
- Teams with strong Java, weak frontend skills
It’s less suited for:
- Highly interactive public-facing websites
- Complex client-side state management
- Teams already proficient in JavaScript frameworks
Common Mistakes to Avoid
Don’t expect SPA capabilities. Vaadin excels at business applications, not complex single-page apps with heavy client-side state. If you need both, use Vaadin for admin panels and React/Angular for public-facing apps.
Don’t ignore JavaScript completely. While not required, understanding basic DOM and CSS helps. JavaScript integration is available when you need third-party widgets.
Don’t treat it like GWT/JSF. Vaadin is more modern than GWT (no widget compilation) and more reactive than traditional JSF.
Comparison with Alternatives
┌────────────────┬─────────────────┬──────────────────────────┐│ Approach │ Learning Curve │ Best For │├────────────────┼─────────────────┼──────────────────────────┤│ Vaadin │ Low (Java only) │ Business apps, tools ││ JTE │ Medium │ Content-heavy sites ││ React/Angular │ High (JS/TS) │ Complex SPAs ││ GWT │ High (legacy) │ Legacy migration │└────────────────┴─────────────────┴──────────────────────────┘Final Thoughts
If you’re a Java developer who wants to ship a web application quickly without investing months in learning the frontend ecosystem, Vaadin is worth serious consideration. It won’t replace React/Angular for all use cases, but for the right scenarios—business applications, internal tools, rapid prototyping—it can be a productivity game-changer.
The Reddit OP’s problem is common, and Vaadin’s popularity in those comments is no accident. It lets you leverage your existing Spring and Java skills to build modern, responsive web UIs without the frontend complexity.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments