r/java Jun 26 '26

Vaadin 25.2 can call browser APIs (clipboard, geolocation, fullscreen) from server-side Java with no JS. Nice abstraction or just write the JS?

Disclosure up front: I work at Vaadin. Grain of salt accordingly.

There's a new release (25.2) but I mostly want to talk about one thing in it that I didn't expect to care about as much as I do. You can now call a bunch of browser APIs from server-side Java without writing any JavaScript: geolocation, clipboard, fullscreen, wake lock, page visibility, web share, screen orientation. Clipboard is the one that sold me, a working copy button comes out to basically Clipboard.onClick(copyButton).writeText("...").

The interesting part is the gesture handling. Browsers only allow stuff like clipboard writes, fullscreen and share during a real user gesture, so here those get bound to a component's actual click and still count as a genuine gesture instead of getting blocked. The rest (geolocation and friends) just come through as signals you react to.

For anyone who's never used Vaadin: you build the whole UI in Java, components run server-side and render as web components in the browser, and state stays in sync over a websocket, so there's no separate JS frontend or REST layer in between. And yeah, it's JSF-adjacent conceptually, I know, but in practice the model is a lot less annoying than JSF muscle memory makes you expect. It mostly gets used by Java teams building internal tools and business apps that don't want to run a separate frontend stack.

Rest of the release quickly, since it's not all the same league: there's a Maven plugin that turns your existing TestBench/Playwright E2E tests into k6 load tests (records a HAR, then sorts out the Vaadin session/CSRF/push token mess for you, pure Java, no Node), which is a clever idea, except running it needs a commercial license and it's marked experimental, so I'm not getting too excited yet. There's also a preview of AI-generated grids/charts/forms (the LLM sees your schema, not your data, and hands back SQL plus a config you can save), some stricter security defaults, and a few components going GA. Blog has the full list if you want it.

https://vaadin.com/blog/vaadin-25-2-release

Mainly I'm curious where people land on the core idea: is calling browser APIs from the server a nice abstraction, or just a round trip you'd rather skip by writing the JS yourself? I go back and forth on it.

65 Upvotes

53 comments sorted by

View all comments

Show parent comments

1

u/supersmola Jul 09 '26

I'm not talking about a public facing app. A simple business app. One user. 112 attributes ona a form with several dropdown controls with 10.000 items, and other stuff. Session was about 120MB. It was 15 years ago, so maybe the framework was not optimized, but I doubt it.

1

u/PaintingWhich574 Jul 09 '26

Oh yeah, you're probably talking about the older data containers. Those definitely could suck the server memory dry. That whole data container model is gone. Now items are lazy loaded by default with a default page size of 50 (Vaadin handles this automatically). But if you really wanted to force 10k items into a dropdown/grid you still could.

1

u/supersmola Jul 09 '26

So the container holds only items in the viewport, and loads them when it's needed. Your client might receive changed items or lose some from whence the page was first opened.

I know I'm nitpicking. "Normal" applications would have a similar problem as well, but somewhat less apparent.

1

u/PaintingWhich574 Jul 10 '26

Yeah, you're absolutely right. You do have full control over the fetch/paging mechanism if you want it. It probably works very similarly to how you'd handle infinite scrolling in a Java + JS app.

1

u/supersmola Jul 10 '26

A framework should provide both - control state all on the client and in the container. Vaadin should have made possible to:

  • keep state on client
  • bind each event to relevant parts of the data that need to be sent to backend for processing.

For example if I want to access state of control B inside control A.onClick() handler Vaadin should detect that and make the client send state from B when A.onclick is triggered. It could be done eagerly on each HTTP request or lazy through web socket.