What's new in version 26.02?

webforJ 26.02 is live! The headline is craftforJ, a visual development environment that runs inside your app and brings a coding agent with it, one that writes Java against the app actually running in front of you. Alongside it, this release opens your views to AI hosts with MCP Apps, adds push notifications and a Card component, brings search to every list component and section labels to AppNav, and makes hotswap the default development loop. See the highlights below, and as always, the GitHub release overview has the complete picture.
craftforJ
craftforJ is a visual development environment that ships with webforJ. It runs inside your app in development mode and gives you a live view of the components your Java code created.
Because craftforJ reads your app through webforJ itself, it describes the app in the terms you wrote it in. The tree lists the components your Java code created rather than the markup the browser rendered, the properties are the ones your components declare, and the routes are the ones your router registered, together with the access rules you annotated them with.
Select a component by clicking it in the page, change its properties, and the running app updates immediately. When a change is worth keeping, craftforJ shows it as a diff against the Java file that created it and writes it back to your source. Theming works the same way: adjust the design tokens your app is built from, then save the result into your stylesheet.
Projects created with startforJ or from a webforJ archetype come with craftforJ enabled, so it's there the first time you run them. Press Alt + Shift + D to open it.
The AI assistant
craftforJ includes a full coding agent, and what separates it from an assistant in your editor is where it sits: inside the app that's running in front of you.
The agent isn't limited to the property changes you could make by hand. Describe a problem and it writes the code for it, adding methods, changing logic, and restructuring a view as the task requires.
Every edit it writes is staged rather than written to disk, and every staged edit goes to a real Java compiler before you see it. The agent reads the diagnostics that come back and fixes its own mistakes first, so what reaches your review is code that already compiles against your running app. Applying a change restarts the app, and the agent waits for the restart, reconnects, and picks its plan up where it left off. A task spanning several edits and restarts runs to completion.
You decide up front how much it may do on its own: stop for approval on every action that has an effect, apply its own edits but ask before removing something, or run autonomously.
craftforJ ships no model of its own, so you choose the one that runs it. Add an API key for a supported provider, or point craftforJ at a model running locally to keep everything on your machine. Your key is stored on the machine running your app, and never in browser storage.
See the craftforJ documentation for the inspector, writing changes to source, routes, theming, and the assistant.
MCP Apps
The other half of the AI story in 26.02 points the opposite way. Where craftforJ brings an assistant into your app, MCP Apps lets an MCP-capable AI app open one of your views inside its own conversation.
The view stays part of the Java app, using the same components, services, routing, and state it uses in a browser. Add @McpApp to a routed view:
@Route("/inventory")
@McpApp(
name = "inventory",
description = "Shows the current inventory for a warehouse.",
displayMode = McpAppDisplayMode.INLINE)
public class InventoryView extends Composite<FlexLayout> {
// view implementation
}
From there, the person and the AI work the same live UI. The AI can supply input when it opens the view, call actions that change what's on screen, and receive context back from the choices the person makes in it, while the person keeps using the rendered webforJ components directly. The route still works at /inventory in a browser.
See the MCP Apps documentation for Spring Boot and servlet setup, opening input, actions, and testing.
Push notifications
26.02 adds push notifications, which reach a user when your app isn't open. The browser subscribes once, your app stores the subscription, and the server sends to it whenever an event calls for it.
Push ships as its own webforj-push module. Subscribing happens in a view, in response to something the user did, and hands back the address of that browser. Sending happens on the server, from any thread, so a click listener, a scheduled job, and a request handler all work the same way.
Card component
26.02 adds the Card component, a surface for grouping related content and actions into a single item. A Card is assembled from slotted regions: a figure, an icon, a title, a caption, header actions, a body, and a footer. A region with no content isn't rendered, so a Card with a body alone is just a framed block of content.
Show Code
- CardOrientationView.java
Beyond the regions, the component covers the presentation choices that usually end up as custom CSS: orientation, a shadow scale, a borderless setting, dividers, and an expanse setting for tighter dashboard tiles.
See the Card documentation for regions, orientation, elevation, dividers, and click handling.
Search in every list
AppNav picked up search in 26.01. In 26.02 it reaches the list components: ChoiceBox, ComboBox, and ListBox all gain an embedded search field that filters items by their text. The field is off by default. Reach the configuration with getSearch(), then turn it on:
Show Code
- ListSearchView.java
Filtering only hides the items that don't match, so indexes and the current selection still refer to the full list. setTerm() filters from code, with or without the field visible, so your own search UI elsewhere on the page can drive the list.
See the Lists documentation for the field settings and filtering from code.
AppNav section labels
AppNav also gains AppNavLabel, a non-interactive heading that titles a run of items. A label applies to every item after it, up to the next label or the end of the menu, so a long menu reads as a few named groups without nesting.
The nav hides a label automatically once its section has no visible items, when a search filters them all out or they've all been pinned to the top of the menu.
Show Code
- AppNavLabelView.java
- AppNavLabelPageView.java
See the AppNav documentation for label prefixes and suffixes, and how labels behave alongside search and pinning.
Hotswap
The development loop gets faster in 26.02. A hotswap tool applies compiled class changes straight to the running app without a restart, and the app keeps its state. The affected part of the page rebuilds instead of the browser reloading everything.
Hotswap is configured out of the box in every 26.02 archetype through the webforJ build plugin, and the run command stays the same. If you have an existing project, it's worth enabling when you upgrade. A single element in the build plugin configuration turns it on.
Two tools are supported. HotswapAgent is open source, and the build plugin downloads and caches it on the first run. JRebel is a commercial product you install and license yourself.
Method body edits apply on any Java virtual machine. Structural changes, such as adding a field or a method, need the -XX:+AllowEnhancedClassRedefinition option, which the JetBrains Runtime provides and the build detects automatically. Without it, a structural change waits for the next restart, with a warning in the build log and a notice in the browser.
Spring DevTools and the Jetty Maven plugin work as they did before. Hotswap is the new default, and the only one of the three that skips the restart entirely.
See the Hotswap documentation for configuration, command line selection, and how each kind of change applies.
Thanks to our new contributors
26.02 includes code from two first-time contributors:
- @coycatz: complete callbacks for
ViewTransition(#1456) and anElementComposite.get()fix (#1406) - @wfouche: consistent code formatting with Spotless (#1489)
Big thanks to both for their contributions! If you've been considering a contribution of your own, the webforJ repository is open, and we read every pull request that comes in.
That's 26.02 in a nutshell! For the complete changelog, see the GitHub release.