Documentation versions (currently viewingVaadin 24)

What is Flow?

Basics of creating an application using Flow.

Vaadin Flow is a framework that allows developers write web applications in 100% Java. Instead of writing HTML, CSS and JavaScript manually, the user interface is constructed from UI components in Java, in a way similar to Swing and JavaFX. HTML, CSS and JavaScript are still there, but they are abstracted away behind a rich Java API while still being accessible when and where needed. But how does it work under the surface?

Flow acts as a remote control for HTML elements in the browser. Those HTML elements can be simple <div>-elements or more complex elements like a <vaadin-grid> web component. Flow controls the attributes, properties and children of these HTML elements and can even perform custom JavaScript invocations. On the server side, there are corresponding Java objects that the developer is interacting with. Flow takes care of keeping the server side Java objects and the client side HTML elements in sync with each other.


The initial HTML that is loaded from the browser only contains some static placeholder elements and Flow’s client side rendering engine script. This script gets the rendering instructions for the initial view. The server sends over the instructions as JSON. The client side rendering engine interprets these instructions and builds or updates the DOM tree in the browser.

What is the DOM?

The DOM, or Document Object Model, is a representation of the structure of a web page. It is a tree structure where every node is an element, such as <div>, <span> or just text. When a browser reads HTML-code, it parses it into a DOM and then uses the DOM tree to render the web page. The DOM can be dynamically modified by JavaScript in order to change the appearance of the web page in the browser.

You can find more information about the DOM here: Document Object Model

If you want to learn how to build your first view with Vaadin Flow, check out the tutorial.

Reacting to Events

When you add a Vaadin Button with a server side click listener to your UI, Flow creates a corresponding <vaadin-button> element with a DOM event listener in the browser. When a user clicks the button, Flow extracts the relevant information from the event and sends it over to the server in an HTTP POST request. The server side part of the framework looks up the corresponding Button object and invokes all the click listeners that have been added to it.

You can find more information about handling events here: Handling Events

Updating the UI

Once the click listeners have been called, the framework collects all the changes that have been made to the server side components and creates a new JSON object with rendering instructions. This JSON object is sent as a response to the HTTP POST request that delivered the click event in the first place. The client side rendering engine interprets these instructions and updates the DOM tree in the browser.

When a user clicks a link in the browser, Flow’s client side router intercepts the click event and prevents the browser from performing the default action of loading a new page. Instead, Flow sends the event to the server to be handled by Flow’s server side router. The server side router looks up the Java class that corresponds to the new view, instantiates it and adds it to the server side component tree in place of the previous view. Since the server side component tree has now changed, a new JSON object with rendering instructions is sent back to the browser, where the client side rendering engine updates the DOM tree.

You can find more information about routing and navigation here: Routing & Navigation

Scrolling and Lazy Loading

It is not only clicks that get sent from the browser to the server. The Vaadin Grid component supports lazy loading. As the user scrolls the grid, more data is lazily loaded from the server. Under the hood, there is a JavaScript callback in the browser that gets called when the grid runs out of data. This callback sends a message to the server-side Grid object, which in turn calls its server side data provider to load more items.

This update operation cannot be done by manipulating the DOM tree. Instead, the client-side data provider has a function that needs to be called when new data is available. Once the items have been loaded by the server, they are turned into a custom JavaScript function call. This function call ends up as an instruction in the JSON response that the server sends back to the browser. The client side rendering engine then interprets this instruction and calls the JavaScript function, letting the client side data provider know that there are new items available.

You can find more information about client-server communication here: Element API