What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
To use an existing React widget in a Vaadin Flow view, wrap it with a Java class that extends ReactAdapterComponent and a TypeScript custom element that extends ReactAdapterElement. The adapter connects the Java component to the React component through named state and events; it does not turn the whole Flow application into a React app.
Choose the right integration
| Approach | Use it when | What it involves |
|---|---|---|
| Wrap a React component | A Flow view needs a particular existing widget, such as a color picker, chart, or input. | A Java wrapper, a TypeScript adapter, and explicit mapping of state and events. |
| Add a React view | The route or page itself benefits from client-side React behavior, for example offline capability or frequent low-latency interaction. | A separate client-side programming model for the view, rather than a wrapper for one widget. See Vaadin’s React view guidance. |
| Build a native Flow component | You are creating new UI and do not need an existing React component. | A Flow component backed by HTML elements or existing Flow components. Vaadin describes the server-component and client-element model in its component guide. |
The steps below follow Vaadin’s React component wrapping guide. API details and package versions can change, so check the linked documentation for the Vaadin version used by your application.
How the bridge works
The integration has three parts: the Java server component, a browser-side custom element, and the React component rendered inside that element. Java sends and reads named state through the wrapper; the adapter exposes that state to React. The wrapped React component does not need to know about Vaadin.
Create the Java wrapper
Extend ReactAdapterComponent, identify the client module with @JsModule, and give the custom element a name with @Tag. Add @NpmPackage when the wrapped component is installed from npm. This trimmed example follows Vaadin’s documented react-colorful integration; its 5.6.1 dependency is the version used in that example, not a statement of the latest release.
#1 Best Overall
@NpmPackage(value = "react-colorful", version = "5.6.1")
@JsModule("./rgba-color-picker.tsx")
@Tag("rgba-color-picker")
public class RgbaColorPicker extends ReactAdapterComponent {
public record RgbaColor(int r, int g, int b, double a) {}
public RgbaColorPicker() {
setColor(new RgbaColor(255, 0, 0, 1.0));
}
public RgbaColor getColor() {
return getState("color", RgbaColor.class);
}
public void setColor(RgbaColor color) {
setState("color", color);
}
public void addColorChangeListener(
SerializableConsumer<RgbaColor> listener) {
addStateChangeListener("color", RgbaColor.class, listener);
}
}
The wrapper offers a typed Java API: application code can set and retrieve an RgbaColor and subscribe to changes without depending on React’s internal props.
Implement the TypeScript adapter
Create the module referenced by @JsModule. Extend ReactAdapterElement, implement render, and use hooks.useState with the same state name used by the Java wrapper.
Rank #2
class RgbaColorPickerElement extends ReactAdapterElement {
protected override render(hooks: RenderHooks): ReactElement | null {
const [color, setColor] = hooks.useState<RgbaColor>('color');
return <RgbaColorPicker color={color} onChange={setColor} />;
}
}
customElements.define('rgba-color-picker', RgbaColorPickerElement);
Here, color connects Java’s setState, getState, and change listener to the adapter’s state hook. The adapter passes the value and setter to the React component using that component’s own prop names, color and onChange. The registration name rgba-color-picker must match the Java @Tag value.
Map state, events, and data
Synchronize state
Use Java’s setState(name, value) to send a value, getState(name, type) to read it, and addStateChangeListener(name, type, listener) to receive client-side updates. In the adapter, hooks.useState(name) supplies the value and setter to React. Initialize required values in the Java constructor; Vaadin documents that this permits initialized state to be restored on refresh when using @PreserveOnRefresh.
Free tools Windows power users keep installed
One-click scans. No signup required.
Send actions that are not state changes
For client actions that are not naturally represented as a state update, the adapter can use hooks.useCustomEvent. Java can register a listener for the element event and read its event data. Choose state for values that should stay synchronized, and events for discrete actions, then define the event data shape on both sides.
Keep object shapes aligned
Vaadin’s reference describes JSON-representable beans and collections for object-valued state. Keep Java record or bean property names aligned with the corresponding TypeScript property names so the serialized object has the shape the client expects.
Rank #4
Expose a React input to Flow Binder
If the wrapped component is a form input, Vaadin’s documented pattern is to wrap the adapter in an AbstractSinglePropertyField implementation. This makes the component usable with Binder. Its Flow property must match the client element’s value behavior: verify how the component initializes, reports changes, and handles programmatic updates in the form workflow.
Check the integration before debugging elsewhere
- Element does not connect: Compare the string in Java’s
@Tagwith the name passed tocustomElements.define; they must be identical. - State is missing or incorrect after refresh: Set the initial state in the Java constructor if the view relies on Vaadin’s documented
@PreserveOnRefreshbehavior. - Updates do not reach React or Java: Check that the state name is identical in Java’s state methods and the adapter’s
hooks.useStatecall, and that the React component receives the correct prop and callback names. - Object properties arrive under unexpected names: Align Java bean or record fields with the client-side data shape.
- The adapter is becoming application logic: Keep it focused on mapping web-component properties and events to React props; keep business logic in the Java application.
These checks follow the API model and cautions in Vaadin’s wrapping documentation and React adapter reference.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

