I'm happy to announce that we're bringing Hilla back under the Vaadin brand as a part of the Vaadin platform. In addition, we're making it more convenient to configure routing so that new view files are automatically registered as routes. Finally, we'll start recommending signals for UI state management. All of these changes are part of the new Vaadin 24.4 release.
Bringing Hilla back home to the Vaadin platform
The story of Hilla started when we observed how frameworks built around reactive client-side rendering solutions such as React, Lit, and Angular were becoming popular for business application development. At the same time, we also realized that our experience with combining the front end and the back end could help improve productivity compared to the typical approach with standalone REST endpoints. We set out to build a framework based on end-to-end type safety for applications that combine TypeScript and Java.
The first step towards Hilla was released roughly four years ago in Vaadin 15 as Vaadin's "client-side development model." We used "Fusion" as a technical name in various places, but the documentation and other similar resources were structured around a vision where Java and TypeScript were used interchangeably to build UIs in Vaadin applications. This approach turned out to make it difficult for users to understand where the boundary goes between the different ways of building UIs. There were also challenges with finding documentation and examples related to your chosen approach when everything was just "Vaadin" in search engines.
Fast forward to 2022, when we released Hilla 1.0 as a separate brand. The distinct name made it easy to find relevant documentation, and the separation also made it clear that Hilla can be used as a standalone framework without combining it with our Flow framework. At the same time, there were also some indications that we had taken the separation too far. One example is when we go to developer conferences with a Vaadin-branded booth but still talk about Hilla with developers who are more interested in building UIs with React. We realized that an adjustment was overdue when we started considering separate Vaadin and Hilla booths at the same conference.
So now that we have tried the extreme approach in both directions, we are finally ready for a “Goldilocks” solution in the middle. Starting from Vaadin 24.4, Hilla is a distinctively branded framework in the Vaadin platform alongside the Flow framework. You can use either framework on its own, or you can choose to build some views or components using Hilla and other views or components using Flow. You find resources for Hilla by searching for "Vaadin Hilla" and resources for Flow by searching for "Vaadin Flow."
This is a regular backward-compatible change for Flow users, whereas package name changes cause some trivial breaking changes for Hilla users. This means that the version for Flow users changes from 24.3 to 24.4, whereas the Hilla version number changes from 2.5 to 24.4. All Maven artifacts for Hilla will be published by the com.vaadin
organization, and all npm modules will be in the @vaadin
scope. We will also gradually move towards sunsetting the hilla.dev website by integrating documentation and other material into vaadin.com/hilla.
Add a view simply by creating a view file
One of the annoyances that I face whenever I want to try out something with Hilla is the ceremony needed to create a new view. In addition to creating the view file itself, I also need to update routes.tsx
to register a route, MainLayout.tsx
to add an entry to the main menu, and in some cases, also update the server-side security configuration to allow anonymous users to bootstrap the application from the URL of the new view.
We will greatly simplify this process with the new filesystem-based option for configuring routes. A React component exported from a file in frontend/views/
is automatically registered as a view with a route based on its location within that directory.
The view file can also define additional configuration, such as how it is loaded and included in the application's main menu.
export const config: ViewConfig = {
loginRequired: true,
menu: {
title: 'A view for me',
order: 3
}
};
export default function MyView() {
return <div>This is my view</div>
}
You can keep using your existing manual route configuration since the new way of configuring routing will only be in effect if there's a line in routes.tsx
to include routes from the views/
directory in the React Router configuration used. If you are already using views/
for manually configured routes, then there might be some cases where you need to rename the directory or disable the Vite plugin that looks inside views/
to avoid interference.
There's also an additional benefit in applications that use both Flow and Hilla views since we can combine the information about both views so that they seamlessly work together.
Getting ready for the next generation of UI state management
The third big change we're introducing is the first steps towards an architecture based on full-stack signals. A signal is a value holder that automatically keeps track of where the value has been used. This fine-grained dependency information will automatically make the framework re-render only the directly affected parts of the UI when the value of a signal has changed.
export default function ClickCounter() {
const [state, setState] = useState(0);
const signal = useSignal(0);
return <>
<button onClick={() => setState(state + 1)}>State: {state}</button>
<button onClick={() => signal.value++}>Signal: {signal}</button>
</>
}
There are two noteworthy details that are not apparent just from the code in this simple example, which compares React's built-in state management API to the signals API. The first is that the render function doesn't run again when the Signal button is clicked since {signal}
automatically creates a simple wrapper component that updates itself based on changes to the signal value. The other difference is that the signal instance could just as well be a singleton imported from some other module, and the text in the button would still automatically react to changes to that signal even without a useSignal
hook in the component.
Signals were originally designed as an alternative to useState
and useContext
but the reason we're so excited about signals goes deeper than that. Hilla's full-stack nature means that the same approach with signals could also be used to synchronize state outside a single browser tab. Signals can be used to share updates between multiple users for any collaborative use case and between the UI and the database as an alternative to explicit updating, fetching, and polling.
The initial phase of our signals vision introduces signals as a replacement for useState
and other cases that stay within the same browser tab. Later in 2024, we will extend this with "full-stack signals" that are synchronized between users through the server. Your existing code using useState
will remain fully functional as we introduce additional functionality based on signals.
You can try it right now
Those are the highlights of what we're releasing for Hilla in Vaadin 24.4. The framework is fully integrated with the Vaadin platform. Router configuration is much simpler thanks to a convention based on file system paths, and the introduction of signals will pave the way for a new paradigm in client-server communication.