v3.0.0
Focus on **performance, architecture flexibility, and cleaner integration APIs**.
🚀 Focus on performance, flexibility, and a cleaner UX.
Release date: March 5, 2026
This release focuses on performance, architecture flexibility, and cleaner integration APIs. Several internal improvements significantly improve canvas interaction performance, while architectural refactors make Weave.js more extensible and framework-agnostic.
In addition, some tools were updated to remove reliance on global browser state and improve media handling workflows.
Changes
Improved Image Tool UX
The Image Tool workflow has been redesigned to provide a simpler and more responsive upload experience.
- Async persistence for uploaded images, upload now is performed async from adding the image to the canvas
- Simplified image upload flow
- Faster visual feedback when inserting images
- Reduced UI blocking during upload or persistence operations
- Removed global
window.weaveproperties.
Images can now be inserted and manipulated on the canvas while persistence happens asynchronously, improving responsiveness in collaborative environments.
https://github.com/InditexTech/weavejs/issues/941
Removed global window.weave dependency from Video Tool
The Video Tool no longer relies on global window.weave properties.
- Easier integration with framework-based applications
- Better compatibility with SSR and modular environments
Video tool configuration must now be passed explicitly instead of relying on global variables.
https://github.com/InditexTech/weavejs/issues/943
Removed global window.weave dependency from Text Tool
The Text Tool has been updated to remove usage of global configuration via window.weave.
- Easier integration with framework-based applications
- Better compatibility with SSR and modular environments
This aligns the Text Tool with the architecture used across other tools.
https://github.com/InditexTech/weavejs/issues/944
Improved performance of group / un-group operations
Grouping and un-grouping nodes has been optimized to handle large selections more efficiently.
- Reduced processing overhead during group creation
- Faster un-group operations
- Improved performance when manipulating large node collections
These improvements are especially noticeable when working with large collaborative canvases.
https://github.com/InditexTech/weavejs/issues/948
Improved drag and transform performance
Canvas interaction performance has been improved during dragging and transformation operations.
- Smoother dragging with many nodes on the canvas
- Reduced layout recalculations
- Optimized transformer update logic
These changes significantly improve usability in large or complex scenes.
https://github.com/InditexTech/weavejs/issues/950
Renderer and reconciler architecture refactor
Weave.js now supports different state renderers and reconcilers, making the rendering pipeline more flexible.
- Decoupled state reconciling from rendering implementation
- Ability to plug in custom renderers / reconcilers
- Cleaner internal architecture
As today we provide two renderer / reconcilers, bot over Konva.js in two new packages:
@inditextech/weave-renderer-konva-base
A simplified renderer without the React Reconciler overhead. Super-performant. (Recommended).
@inditextech/weave-renderer-konva-react-reconciler
The React Reconciler renderer previously provider on past versions.
This change enables future integrations beyond the current renderer implementation.
https://github.com/InditexTech/weavejs/issues/953
### Removed heartbeat mechanism from Azure Web PubSub store
The heartbeat mechanism previously used in the Azure Web PubSub store has been removed. This mechanism introduced problems
specially when switching tabs due that setTimeout and setInterval apis are not executed when tab is not focused.
https://github.com/InditexTech/weavejs/issues/956
Breaking Changes
Provide Image data to Image Tool
The Image Tool no longer fetches the image automatically from an URL.
Instead, the image data (dataURL) must be passed explicitly via the imageData option when triggering the tool.
Before (v2.x)
# After user picks the image to add from filesystem
const persistedImageURL = await uploadImage(...);
const { nodeId, finishUploadCallback } = instance.triggerAction("imageTool",
{
imageId: resourceId,
imageURL: persistedImageURL,
...
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
) as any;For Drag & Drop, normally on the onDragStart event we setup the same info on the weaveDragImageURL and weaveDragImageId
properties on the window object.
<div
...
onStartDrag={() => {
window.weaveDragImageId = // dragged image id probably from data-*
window.weaveDragImageURL = // dragged image URL probably from data-*
}}
...
>
...
</div>After (v3.0.0)
Applications are now responsible for retrieving the image data and passing it to the tool call:
# After user picks the image to add from filesystem
const instance = new Weave(...); // Weave Instance
const resourceId = "my-resource-id";
const reader = new FileReader();
reader.onloadend = () => {
const { nodeId, finishUploadCallback } = instance.triggerAction("imageTool",
{
imageId: resourceId,
imageData: reader.result as string,
...
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
) as any;
// Perform upload to application persistence
const persistedImageURL = await uploadImage(...);
finishUploadCallback?.(
nodeId,
persistedImageURL
);
}
reader.onerror = () => {
// Handle error
};
reader.readAsDataURL(file);
const roomId = "my-room";
const store = new AzureWebPubSubStore(
{
getUser: ...
},
{
roomId,
...
});For Drag & Drop, now the Image Tool provides an API to inform the URL and Id properties, take into account that you now also need to pass the original image real width and height (without any scaling process):
<div
...
onStartDrag={() => {
const imageTool = instance.getActionHandler(
IMAGE_TOOL_ACTION_NAME,
) as WeaveImageToolAction | undefined;
if (!imageTool) {
return;
}
imageTool.setDragAndDropProperties({
imageURL: e.target.src,
imageId: e.target.dataset.imageId,
imageWidth: e.target.naturalWidth,
imageHeight: e.target.naturalHeight,
});
}}
...
>
...
</div>Define a renderer on the Weave.js instance
Weave instance no defines a renderer / reconciler.
Instead, you need to define a renderer / reconciler and pass it down to the Weave.js instance.
Before (v2.x)
# Without React
const store = new WeaveStore();
const weaveEle = // Weave DOM element
const weaveEleClientRect = weaveEle?.getBoundingClientRect();
const instance = new Weave({
store,
...
}, {
container: weaveEle as HTMLDivElement,
width: weaveEleClientRect?.width ?? 1920,
height: weaveEleClientRect?.height ?? 1080,
});
# With the React helper
const store = new WeaveStore();
<WeaveProvider
getContainer={() => {
return document?.getElementById("weave") as HTMLDivElement;
}}
store={store}
...
>
...
</WeaveProvider>Before (v3.0.0)
# Without React
const store = new WeaveStore();
const weaveEle = // Weave DOM element
const weaveEleClientRect = weaveEle?.getBoundingClientRect();
const reactReconcilerRenderer = new WeaveKonvaReactReconcilerRenderer();
// const baseRenderer = new WeaveKonvaBaseRenderer();
const instance = new Weave({
store,
renderer: reactReconcilerRenderer,
...
}, {
container: weaveEle as HTMLDivElement,
width: weaveEleClientRect?.width ?? 1920,
height: weaveEleClientRect?.height ?? 1080,
});
# With the React helper
const store = new WeaveStore();
const reactReconcilerRenderer = new WeaveKonvaReactReconcilerRenderer();
// const baseRenderer = new WeaveKonvaBaseRenderer();
<WeaveProvider
getContainer={() => {
return document?.getElementById("weave") as HTMLDivElement;
}}
store={store}
renderer: reactReconcilerRenderer,
...
>
...
</WeaveProvider>Migration steps
- Update your Image Tools (from filesystem or when drag & drop).
- Instantiate a renderer / reconciler and pass it on the
rendererproperty of Weave.js constructor or React provider.
This change gives applications full control over renderer / reconciler, simplifies and streamlines the Image Tool UX and allows Weave.js to scale better with large rooms.
