Choosing Between Vaadin Flow and Vaadin Fusion: A Practical Decision Guide
Decide whether Vaadin Flow or Fusion is right for your next project. Compare server‑side and client‑side rendering, trade‑offs, and see a concrete example that runs both in a single Spring Boot app.
29 May 2026, 07:09 UTC

Decision
When starting a new Vaadin 23+ application you must decide whether to render the UI on the server with Vaadin Flow or on the client with Vaadin Fusion. The choice is driven by team skill sets, SEO needs, and the level of client‑side interactivity required.
Constraints
- Vaadin version must be ≥23 LTS (both Flow and Fusion are fully supported).
- A Java backend (Spring Boot or plain servlet) must be available.
- Fusion requires a modern browser that supports ES2020.
- Team must have either Java (Flow) or TypeScript/JavaScript (Fusion) expertise.
- Build tooling: Flow uses Maven/Gradle; Fusion needs Node.js and npm/Yarn.
Option Comparison
| Feature | Vaadin Flow (SSR) | Vaadin Fusion (CSR) |
|---|---|---|
| Rendering model | Server‑side Java components, initial HTML + minimal JS | Client‑side TypeScript components, full JS bundle |
| Initial page load | Fast HTML rendering, good for SEO and first‑paint | Longer bundle download, slower first paint |
| Interactivity | Java‑backed event handling, limited to server round‑trips | Rich client‑side logic, offline capabilities |
| Server load | Higher CPU/memory per session (UI state kept on server) | Lower server load (stateless UI) |
| Security integration | Direct Java access to security context | Requires API endpoints for data, security handled via REST/OData |
| Build tooling | Maven/Gradle, no Node required | Node + npm/Yarn, requires frontend build step |
| Debugging | Java stack traces, easier server‑side debugging | Browser dev tools, TypeScript debugging, requires source maps |
| SEO friendliness | Excellent – server renders full HTML | Good if using server-side rendering or pre-render hooks, otherwise less |
Trade‑offs
- Flow is ideal when you need fast initial loads, tight security integration, or when your team is comfortable with Java only. It keeps the UI state on the server, which simplifies security but can become a bottleneck under high concurrency.
- Fusion shines for applications that require heavy client‑side logic, offline support, or a clear separation between UI and business logic. The larger JS bundle and build step add complexity, and you must expose data via REST/OData endpoints.
- Mixing Flow and Fusion in the same UI tree is discouraged; if you need both, route them separately.
- Fusion’s build time increases CI duration; consider caching node modules and using incremental builds.
Concrete Implementation Example
Below is a minimal starter that demonstrates both approaches in the same project. The project uses Spring Boot 3.2, Maven, and Node 20.
1. Project Setup
mvn archetype:generate \
-DarchetypeGroupId=com.vaadin \
-DarchetypeArtifactId=vaadin-archetype-application \
-DarchetypeVersion=23.3.0 \
-DgroupId=com.example \
-DartifactId=vaadin-demo \
-Dpackage=com.example.demo \
-Dversion=0.0.1-SNAPSHOT \
-DinteractiveMode=false
cd vaadin-demo
2. Add Fusion Support
Open pom.xml and add the Fusion starter dependency:
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-fusion-starter</artifactId>
<version>23.3.0</version>
</dependency>
Install Node and npm (or Yarn) globally if not already installed.
3. Create a Flow View
File: src/main/java/com/example/demo/views/flow/HelloFlow.java
package com.example.demo.views.flow;
import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
@Route("flow")
public class HelloFlow extends VerticalLayout {
public HelloFlow() {
add(new H1("Hello from Vaadin Flow"));
}
}
4. Create a Fusion View
File: src/main/java/com/example/demo/views/fusion/HelloFusion.java
package com.example.demo.views.fusion;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.server.auth.AnonymousAllowed;
@Route("fusion")
@AnonymousAllowed
public class HelloFusion extends VerticalLayout {
public HelloFusion() {
add(new com.vaadin.flow.component.html.H1("Hello from Vaadin Fusion"));
}
}
Fusion automatically generates a fusion/HelloFusion.tsx component that renders the same UI on the client.
5. Build and Run
# Build Java and compile TypeScript
mvn clean install
# Run the Spring Boot app
mvn spring-boot:run
Navigate to /flow and /fusion to see both views.
6. Verify the Difference
- Open the browser DevTools and inspect the Network tab.
- The Flow route should load
index.html, a smallvaadin.jsbundle, and minimal JavaScript. - The Fusion route should load a larger
fusion.jsbundle (typically 200‑400 KB gzipped) plus the generatedHelloFusion.tsxJavaScript.
- The Flow route should load
- Use a simple load test (e.g.,
jmeterorwrk) to compare CPU usage. Under 100 concurrent users, Flow will show higher CPU per thread due to server‑side state management, whereas Fusion will have lower CPU but higher network traffic.
Validation Checklist
- Confirm both routes load without errors in a supported browser.
- Verify that Flow’s page source contains the full H1 markup before JavaScript executes.
- Check that Fusion’s source includes a
class HelloFusion extends Componentdefinition in the compiled bundle. - Run a simple CPU profiling on the Spring Boot process to observe the expected load difference.
Summary
Choose Vaadin Flow when you need fast initial rendering, strong server‑side security, and a Java‑only stack. Opt for Vaadin Fusion if your application demands rich client‑side logic, offline capabilities, or a TypeScript‑centric development experience. Both approaches can coexist in a single project, but keep them on separate routes to avoid complexity.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.