Vaadin Flow 24.3 introduces quality-of-life improvements, simplified component styling, and more.

The Web App Platform for Java Developers

Business apps shouldn't suck. With Vaadin you can craft stunning
full-stack web apps at lightning speed
. Scaling from hobby projects to enterprise.

Latest:
24.3.5

Two ways of coding the UI

Flow: The most productive way is just pure Java

Hilla: Full power of React with type-safe communication

My Leads
Spring Boot
UI
                                                    
                                                        @Route("flow")
                                                        public class FlowView extends VerticalLayout {
                                                        
                                                            public FlowView(PersonService service) {
                                                                var datePicker = new DatePicker("Born on");
                                                                var grid = new Grid<>(Person.class);
                                                        
                                                                datePicker.addValueChangeListener(event -> {
                                                                    grid.setItems(service.getPeopleBornOn(event.getValue()));
                                                                });
                                                        
                                                                add(datePicker, grid);
                                                            }
                                                        }
                                                    
Services
                                                        
                                                            @BrowserCallable
                                                            @Service
                                                            @AnonymousAllowed
                                                            public class PersonService {
                                                            
                                                                public List
                
                
                 
                  getPeopleBornOn(LocalDate date) {
                                                            
                                                                    String[] randomFirstNames = { "John", "Jane", "Mary", "Patricia", "Robert", "Michael", "James", "William",
                                                                        "David", "Richard", "Charles", "Joseph", "Thomas", "Christopher", "Daniel", "Paul", "Mark", "Donald",
                                                                        "George", "Kenneth", "Steven", "Edward", "Brian", "Ronald", "Anthony", "Kevin", "Jason", "Matthew",
                                                                        "Gary", "Timothy", "Jose", "Larry", "Jeffrey", "Frank", "Scott", "Eric", "Stephen", "Andrew", "Raymond",
                                                                        "Gregory", "Joshua", "Jerry", "Dennis", "Walter", "Patrick", "Peter", "Harold", "Douglas", "Henry",
                                                                        "Carl", "Arthur", "Ryan", "Roger" };
                                                                    String[] randomLastNames = { "Smith", "Johnson", "Williams", "Brown", "Jones", "Miller", "Davis", "Garcia",
                                                                        "Rodriguez", "Wilson", "Martinez", "Anderson", "Taylor", "Thomas", "Hernandez", "Moore", "Martin",
                                                                        "Jackson", "Thompson", "White", "Lopez", "Lee", "Gonzalez", "Harris", "Clark", "Lewis", "Robinson",
                                                                        "Walker", "Perez", "Hall", "Young", "Allen", "Sanchez", "Wright", "King", "Scott", "Green", "Baker",
                                                                        "Adams", "Nelson", "Hill", "Ramirez", "Campbell", "Mitchell", "Roberts", "Carter", "Phillips", "Evans",
                                                                        "Turner", "Torres", "Parker", "Collins", "Edwards" };
                                                                    ArrayList
                 
                 
                  
                   people = new ArrayList<>();
                                                                    for (int i = 0; i < 100; i++) {
                                                                        people.add(new Person(randomFirstNames[(int) (Math.random() *
                                                                        randomFirstNames.length)], randomLastNames[(int) (Math.random() * randomLastNames.length)], date));
                                                                    }
                                                                    return people;
                                                                }
                                                            }
                                                       
                 
                 
                
                
                                                       
Data
                                                        
                                                            public final class Person {
                                                                private String firstName;
                                                                private String lastName;
                                                                private LocalDate birthDate;
                                                                // getters and setters
                                                            }  
                                                       
                                                       
Database
Kubernetes
My Leads
UI
                                                 
                                                     export default function HillaView() {
                                                         const [people, setPeople] = useState
              
              
               
               ([]);
                                                         const [date, setDate] = useState('');
                                                     
                                                         useEffect(() => {
                                                             PersonService.getPeopleBornOn(date).then(setPeople);
                                                         }, [date]);
                                                     
                                                         return (
                                                             <div className="flex flex-col gap-m items-start p-m">
                                                             <DatePicker label="Born on"
                                                                 onValueChanged={e => setDate(e.detail.value)} />
                                                             <Grid items={people} >
                                                                 <GridSortColumn path="birthDate" />
                                                                 <GridSortColumn path="firstName" />
                                                                 <GridSortColumn path="lastName" />
                                                             </Grid>
                                                         </div >
                                                         );
                                                     }
                                                 
              
              
Spring Boot
Services
                                                                
                                                                    @BrowserCallable
                                                                    @Service
                                                                    @AnonymousAllowed
                                                                    public class PersonService {
                                                                    
                                                                        public List
                
                
                 
                  getPeopleBornOn(LocalDate date) {
                                                                    
                                                                            String[] randomFirstNames = { "John", "Jane", "Mary", "Patricia", "Robert", "Michael", "James", "William",
                                                                                "David", "Richard", "Charles", "Joseph", "Thomas", "Christopher", "Daniel", "Paul", "Mark", "Donald",
                                                                                "George", "Kenneth", "Steven", "Edward", "Brian", "Ronald", "Anthony", "Kevin", "Jason", "Matthew",
                                                                                "Gary", "Timothy", "Jose", "Larry", "Jeffrey", "Frank", "Scott", "Eric", "Stephen", "Andrew", "Raymond",
                                                                                "Gregory", "Joshua", "Jerry", "Dennis", "Walter", "Patrick", "Peter", "Harold", "Douglas", "Henry",
                                                                                "Carl", "Arthur", "Ryan", "Roger" };
                                                                            String[] randomLastNames = { "Smith", "Johnson", "Williams", "Brown", "Jones", "Miller", "Davis", "Garcia",
                                                                                "Rodriguez", "Wilson", "Martinez", "Anderson", "Taylor", "Thomas", "Hernandez", "Moore", "Martin",
                                                                                "Jackson", "Thompson", "White", "Lopez", "Lee", "Gonzalez", "Harris", "Clark", "Lewis", "Robinson",
                                                                                "Walker", "Perez", "Hall", "Young", "Allen", "Sanchez", "Wright", "King", "Scott", "Green", "Baker",
                                                                                "Adams", "Nelson", "Hill", "Ramirez", "Campbell", "Mitchell", "Roberts", "Carter", "Phillips", "Evans",
                                                                                "Turner", "Torres", "Parker", "Collins", "Edwards" };
                                                                            ArrayList
                 
                 
                  
                   people = new ArrayList<>();
                                                                            for (int i = 0; i < 100; i++) {
                                                                                people.add(new Person(randomFirstNames[(int) (Math.random() *
                                                                                randomFirstNames.length)], randomLastNames[(int) (Math.random() * randomLastNames.length)], date));
                                                                            }
                                                                            return people;
                                                                        }
                                                                    }
                                                               
                 
                 
                
                
                                                               
Data
                                                                
                                                                    public final class Person {
                                                                        private String firstName;
                                                                        private String lastName;
                                                                        private LocalDate birthDate;
                                                                        // getters and setters
                                                                    }  
                                                               
                                                               
Database
Kubernetes
Fighting for simplicity with end-to-end ownership

Full-stack way of thinking

We believe that a full-stack approach is the most productive way of crafting high-quality applications: A development team should own a feature from the back-end to the front-end, rather than dividing tasks between separate front-end and back-end teams. By avoiding communication barriers, a team can iterate drastically faster - not only shipping faster, but also with better quality.


The chosen software stack should align with this organization structure:
reducing complexity through a unified full-stack framework.

PRODUCTIVITY
CONTROL

Flow

Components
Flow
Spring Boot
Vaadin Flow is the most productive way of building web applications with a Spring backend because it eliminates the need to write any JavaScript or HTML. Developers write the user interface in pure Java using feature rich components, while Vaadin takes care of rendering, communication, and event handling.

Hilla

Components
React
Hilla
Spring Boot
Vaadin Hilla is a perfect bridge between React and Spring backend. It automates and secures the communication from React to the Java server, generating a TypeScript-based API for your services written in Java. Furthermore, it includes Vaadin’s powerful user interface components and fully integrates them with React.

Next.js

Components
React
Next.js
Node.js
Next.js is the most popular full-stack framework for React, and for good reason: It allows a frontend team to extend their reach by writing backend services. While Vaadin is the optimal choice for teams who prefer Java for their backend, Next.js is the best choice for teams who opt to write their backend in TypeScript on Node.js.

Decoupled

Components
React or Angular
REST or GraphQL
Backend of choice
Unlike full-stack frameworks, a fully decoupled stack not only permits but also necessitates a team to select and maintain different technologies for each layer of the stack. This approach may be favored when an organization opts to have separate backend and frontend teams, or when there is limited control over some of the layers.
Secure by default
Vaadin automates the communication between the browser and the server. This not only makes Vaadin extremely productive to use, but it also secures all communication by default. You no longer have to wonder if you've left a REST endpoint unsecured or if you're handling network input in an unsafe way: automated session keys, input type checking, and server-side validation are on by default to safeguard your application. Furthermore, support for Spring Security and optional SSO are there to make building all levels of security into your application easy.
Batteries included
Vaadin is a complete system that works out of the box, providing you with a platform to build on. It includes web frameworks, comprehensive user interface components, a Figma-based design system, tools for building user interfaces, and a testing system. These help you get started quickly and scale your application to even the most demanding use-cases. Vaadin further saves your time by ensuring that all dependencies are, and continue to be, well-tested and integrated to work together.
Real-time communication
When each layer of the stack is seamlessly working together, user interface components can stream data from the backend. This automates tasks such as pushing user interface updates over websockets and lazy loading while scrolling through vast amounts of data. Furthermore, the Vaadin platform comes with built-in features similar to Google Docs' multiplayer editing functions, enabling real-time collaboration between your end users. This enriches the user experience without the need for significant development investment.
  • Beautiful UI Components
Vaadin UI Components

Powerful UI Components are
the foundation for a great UX

Accessible , Beautiful, Consistent

Optimize developer productivity by building from a set of feature rich
web components built-in to Vaadin. They are optimized for data heavy business
applications and include API for both Java or with React. 

Based on the open W3C Web Components standard, ensuring that they work natively in all modern browsers and can be used with virtually any front-end framework.

Vaadin components work with screen readers and assistive devices so everyone can use your app. Conforms to the WCAG 2.1 AA standard, and EU and US accessibility regulations.

Easy theming through a set of global CSS properties. Additionally, a powerful CSS injection mechanism is available for advanced custom styling.

The high quality, high fidelity Figma library makes it easy to create mockups and prototypes of Vaadin-based UIs.

Use Java APIs with Vaadin Flow, or TypeScript APIs with Hilla and other front-end frameworks.

A good base for your own design system, complete with a toolkit for setting up a documentation website.

Built for business

Open Source
The core of the product is licensed under permissive Apache 2.0 license. Commercial features are available where we can add value beyond the fully functional core.
First party support
Vaadin is built by a company named Vaadin. Since 2000. Our team has supported thousands of organizations building their applications.
15-year maintenance
Business applications should have a long lifespan. Up to 15 years of support is available for each version. Migrations are supported by automated tooling.

Powering the enterprise

Loved by 100,000+ developers and relied on by some of the largest organizations on the planet.
Everything from banks, insurance, health care, to aerospace, and government.
Customer stories

Start building with Vaadin now!

We are here to help you succeed. Our specialists are happy to answer any questions you may have, and our technical documentation includes tutorials and copy-paste code
examples on the different Vaadin features.