CheckList
Description
Is your feature request related to a problem? Please describe.
Currently, when developers need to attach custom application-specific data to Fabric.js objects (e.g., database IDs, metadata, business logic flags), they have to manually extend the toObject/toJSON methods or rely on the customProperties static field . While these methods work, they lead to fragmentation:
Inconsistency: Every project implements custom property handling differently (some override prototypes, others pass property arrays to toJSON).
Verbose API: Calling canvas.toJSON(['customId', 'metaData']) every time is repetitive and error-prone .
Type Safety Issues: In TypeScript projects, manually extending interfaces for every new property adds boilerplate .
A dedicated, officially supported container for custom data would unify these practices.
Describe the solution you'd like
I propose adding a standard userData property (of type any or object) to all fabric.Object instances. This property would serve as a reserved namespace for developers to store arbitrary data.
Key Requirements:
Automatic Serialization: The userData object should be included by default in the JSON output of toObject() and toJSON() without requiring additional parameters .
Deserialization Support: When using canvas.loadFromJSON(), the data should be automatically restored back to the userData property of the recreated objects .
TypeScript Integration: The IObjectOptions interface should be updated to include userData?: any; to allow for type-safe extensions via generics .
// Creating an object with user data
const rect = new fabric.Rect({
left: 10,
top: 10,
width: 20,
height: 20,
userData: {
id: 'abc-123',
editable: true,
tags: ['important', 'draft']
}
});
canvas.add(rect);
// Serialization - userData is automatically included
const json = JSON.stringify(canvas.toJSON());
// Expected output contains: "userData":{"id":"abc-123","editable":true,"tags":[...]}
// Deserialization - userData is automatically restored
canvas.loadFromJSON(json, () => {
console.log(canvas.item(0).userData.id); // 'abc-123'
});
Static customProperties: Currently, we can set fabric.Object.prototype.customProperties = ['userData'] . However, this is a workaround that isn't obvious to new users and feels like configuring a global rather than using a built-in feature.
Overriding toObject: Manually extending the prototype to include custom properties works but pollutes the prototype chain and can lead to conflicts if multiple libraries do this .
Property Arrays: Passing property names to toJSON() every time is not a sustainable API for large applications .
Additional context
This feature is common in many mature graphics libraries (e.g., Konva.js has a similar attrs or id pattern) and would significantly reduce boilerplate for developers building complex applications on top of Fabric.js (like design tools, diagram editors, etc.).
The implementation would likely involve modifying the core serialization logic in src/shapes/object.class.js to include this.userData in the default property set, similar to how id or data might be handled.
No response
CheckList
Description
Is your feature request related to a problem? Please describe.
Currently, when developers need to attach custom application-specific data to Fabric.js objects (e.g., database IDs, metadata, business logic flags), they have to manually extend the toObject/toJSON methods or rely on the customProperties static field . While these methods work, they lead to fragmentation:
Inconsistency: Every project implements custom property handling differently (some override prototypes, others pass property arrays to toJSON).
Verbose API: Calling canvas.toJSON(['customId', 'metaData']) every time is repetitive and error-prone .
Type Safety Issues: In TypeScript projects, manually extending interfaces for every new property adds boilerplate .
A dedicated, officially supported container for custom data would unify these practices.
Describe the solution you'd like
I propose adding a standard userData property (of type any or object) to all fabric.Object instances. This property would serve as a reserved namespace for developers to store arbitrary data.
Key Requirements:
Automatic Serialization: The userData object should be included by default in the JSON output of toObject() and toJSON() without requiring additional parameters .
Deserialization Support: When using canvas.loadFromJSON(), the data should be automatically restored back to the userData property of the recreated objects .
TypeScript Integration: The IObjectOptions interface should be updated to include userData?: any; to allow for type-safe extensions via generics .
Static customProperties: Currently, we can set fabric.Object.prototype.customProperties = ['userData'] . However, this is a workaround that isn't obvious to new users and feels like configuring a global rather than using a built-in feature.
Overriding toObject: Manually extending the prototype to include custom properties works but pollutes the prototype chain and can lead to conflicts if multiple libraries do this .
Property Arrays: Passing property names to toJSON() every time is not a sustainable API for large applications .
Additional context
This feature is common in many mature graphics libraries (e.g., Konva.js has a similar attrs or id pattern) and would significantly reduce boilerplate for developers building complex applications on top of Fabric.js (like design tools, diagram editors, etc.).
The implementation would likely involve modifying the core serialization logic in src/shapes/object.class.js to include this.userData in the default property set, similar to how id or data might be handled.
No response