Java Frontend Frameworks

Want to build what users actually see in a web app, but you prefer Java? Java frontend frameworks let you do much of that work in Java. This guide explains the main ones (Vaadin, Jakarta Faces and Thymeleaf), how they differ from JavaScript frontends, and which to pick.

What are Java frontend frameworks?

A Java frontend framework helps you build a web app's user interface using Java on the server. The framework turns your Java code or templates into HTML, CSS and JavaScript, then sends that to the browser. You get buttons, forms and tables without hand-writing every browser detail.

If browsers can't run Java, how does this work?

Right: browsers only understand HTML, CSS and JavaScript. So these frameworks run on the server. They build the page there and send the result to you. Think of a restaurant kitchen: Java cooks the meal, and the browser is the table where it is served.

How do they differ from JavaScript frontends?

Java frameworks build the interface on the server, while JavaScript frameworks (such as React or Angular) run the interface inside the browser. Java options mean fewer languages to learn. JavaScript options give you more control over how the page feels.

Java server-side UIJavaScript frontend
Where the UI is builtOn the serverIn the browser
Main languageJavaJavaScript or TypeScript
Talks to the backend byCalling Java code directlyCalling a REST API
Good forInternal tools, business appsRich public sites and apps
Trade-offLess control over fine detailA second language and toolchain

What is Vaadin?

Vaadin Flow is a framework for building web applications "with only Java," as its documentation puts it. You create the interface from Java components, and Vaadin handles the communication with the browser. HTML and JavaScript are still available when you need something custom.

Here is a complete view. Drop it into a Vaadin project (the Vaadin starter creates one for you) and you get a page with a text box and a button, built only from Java objects:

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.router.Route;

@Route("")                       // show this view at the home page
public class HelloView extends VerticalLayout {

    public HelloView() {
        TextField name = new TextField("Your name");
        Button greet = new Button("Say hello",
            e -> Notification.show("Hello, " + name.getValue()));
        add(name, greet);        // put both on the screen
    }
}
  • The import lines — bring in Vaadin's ready-made components and the routing annotation.
  • @Route("") — maps this class to a web address. The empty string means the home page.
  • VerticalLayout — a container that stacks things top to bottom.
  • TextField and Button — Java objects that become a text box and a button.
  • The lambda e -> ... — runs on the server when someone clicks. name.getValue() reads what was typed.
  • add(name, greet) — places both components in the layout, in that order.

Where does the JavaScript go?

You don't write it. Vaadin ships its own browser code that draws the components and sends each click back to your Java class. When you change a component in Java, Vaadin updates the page for you.

Read more in the Vaadin Flow documentation.

What is Jakarta Faces (JSF)?

Jakarta Faces, formerly JavaServer Faces (JSF), is the Jakarta EE standard for building web UIs. It covers UI components, state, events, validation, navigation, internationalization and accessibility. Version 4.1 ships with Jakarta EE 11, and 5.0 is planned for Jakarta EE 12.

You describe each page in a Facelets file (XHTML with component tags) and connect the tags to a Java class called a backing bean. Here is the same "say hello" screen. First the page, hello.xhtml:

<!DOCTYPE html>
<html lang="en" xmlns:h="jakarta.faces.html">
<h:head><title>Hello</title></h:head>
<h:body>
  <h:form>
    <h:inputText value="#{helloBean.name}" />
    <h:commandButton value="Say hello" action="#{helloBean.greet}" />
    <h:outputText value="#{helloBean.message}" />
  </h:form>
</h:body>
</html>
  • xmlns:h="jakarta.faces.html" — lets the page use the standard HTML component tags with the h: prefix.
  • h:inputText, h:commandButton, h:outputText — a text box, a button and a piece of text.
  • #{helloBean.name} — an expression that links the tag to the name property of the Java bean below.
  • action="#{helloBean.greet}" — calls the bean's greet() method when the button is clicked.

Then the backing bean, HelloBean.java:

import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;

@Named              // the page finds this bean as "helloBean"
@RequestScoped      // a fresh bean for each request
public class HelloBean {

    private String name;
    private String message;

    public void greet() {
        message = "Hello, " + name;
    }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getMessage() { return message; }
}
  • @Named — makes the class available to the page under its name with a lower-case first letter.
  • @RequestScoped — Jakarta EE creates the bean for one request and throws it away afterwards.
  • Getters and setters — Faces calls setName with what was typed, then getMessage to show the result.

It is a good fit when your project already follows Jakarta EE. See the Jakarta Faces specification page and the Jakarta EE tutorial on Facelets.

What is Thymeleaf?

Thymeleaf is a server-side Java template engine. You write an ordinary HTML file with small attributes such as th:text, and Thymeleaf fills them with data on the server. Because browsers ignore those attributes, the file still opens as a plain design preview.

<p th:text="${'Hello, ' + user.name}">Hello, placeholder</p>
<a th:href="@{/books}">See all books</a>
  • th:text — replaces the text inside the tag with the result. It is HTML-escaped by default, which helps protect against injected markup.
  • ${...} — reads a value your Java code supplied.
  • @{...} — builds a web link.

It pairs naturally with Spring Boot. See the official Thymeleaf tutorial.

How do Vaadin, Jakarta Faces and Thymeleaf compare?

All three Java frontend frameworks build the page on the server. The difference is how you describe it: Vaadin uses only Java classes, Jakarta Faces uses component tags in XHTML pages backed by Java beans, and Thymeleaf uses plain HTML files with a few extra attributes. Pick the style your team finds easiest to read.

Vaadin FlowJakarta FacesThymeleaf
You write the UI inJava classesXHTML pages with component tagsHTML templates
Java code lives inThe same view classA backing beanA controller (often Spring MVC)
Clicks are handled byJava listeners on the serverBean methods on the serverA normal form submit or link
Usually paired withSpring Boot (the starter's default)A Jakarta EE serverSpring Boot
Feels closest toBuilding a desktop appWiring up a form designerWriting a web page by hand

Which Java frontend framework should you choose?

Pick Vaadin if you want to stay in Java, Thymeleaf for classic server-rendered pages, and Jakarta Faces if you work in Jakarta EE. For rich public sites, pair a Java backend with a JavaScript frontend. Choose one below:

What fits your project?

I only know Java

Try Vaadin Flow.

  • Build screens from Java components
  • Forms, grids and routing are covered in its docs
  • Good for internal tools and dashboards

Classic pages with Spring Boot

Use Thymeleaf.

  • Write normal HTML with small placeholders
  • The server sends finished pages
  • Easy to add a little JavaScript where needed

Jakarta EE application

Use Jakarta Faces (JSF).

  • The official component-based UI standard of Jakarta EE
  • Handles validation, events and navigation
  • Common in existing enterprise code

Rich public website or app

Use a JavaScript frontend with a Java backend.

  • Java serves data through a REST API
  • The browser app is built with JavaScript or TypeScript
  • Most flexible, but you learn a second language
There is no single winner. Match the tool to your team's skills and the kind of app you are building.

Quick recap

  • Browsers only run HTML, CSS and JavaScript, so Java frontend frameworks build the UI on the server.
  • Vaadin builds screens from Java components; Thymeleaf fills HTML templates; Jakarta Faces is the Jakarta EE UI standard.
  • JavaScript frontends run in the browser and give finer control, at the cost of a second language.

What's next?

See the backend options in Java web frameworks, or learn how a Java backend exposes data to any frontend in Java REST API frameworks.

Frequently Asked Questions

What are Java frontend frameworks?

Java frontend frameworks are tools that help you build the part of a web app users see and click, while you write mostly Java. Examples are Vaadin (Java components), Jakarta Faces (JSF) and Thymeleaf (HTML templates filled in by Java on the server).

Can Java be used for frontend development?

Yes, with a catch. Browsers only run HTML, CSS and JavaScript. Java frontend frameworks run on the server and send the browser the HTML it needs, so you can build screens without writing much JavaScript yourself.

Is Thymeleaf a frontend framework?

Thymeleaf is a server-side template engine. It takes an HTML file with small placeholders and fills them with data from your Java code. It is not a component framework like Vaadin, but it is a very common way to produce pages in Spring Boot apps.

Is JSF still used?

Yes. It is now called Jakarta Faces and is part of Jakarta EE. Version 4.1 belongs to Jakarta EE 11, and 5.0 is in development for Jakarta EE 12. Many existing company applications use it.

Should I learn a Java UI framework or JavaScript?

If you want a simple internal tool or already know Java well, a Java UI framework gets you moving fast. If you want to work on public websites or highly interactive apps, learning JavaScript pays off. Many teams use Java for the backend and JavaScript for the frontend.