ESSerializer
ESSerializer is a JavaScript serialization and deserialization utility. It enables the conversion of JavaScript class instances into JSON format and their subsequent reconstruction back into fully functional objects, ensuring that all Class, Property, and Method information is retained recursively. The library operates without relying on `eval()`, which eliminates a common security vulnerability associated with many serialization methods. ESSerializer supports a broad spectrum of built-in JavaScript classes and types, including various Array types, Date, RegExp, BigInt, and all standard Error classes. It is designed to work seamlessly in both browser and Node.js environments. The current stable version, 1.3.11, receives ongoing maintenance with recent releases focusing on minor bug fixes and security vulnerability patches, indicating an active development and stable release cadence. Its key differentiators include robust recursive class retention, automatic class definition detection during serialization and deserialization, comprehensive support for getter/setter properties and `instanceof` checks, and compatibility with both modern ES6 classes and older function-style class definitions.
Common errors
-
ReferenceError: ClassName is not defined
cause During deserialization, a custom class required for reconstruction was not provided to `ESSerializer.deserialize()`.fixPass all custom class definitions as an array to `ESSerializer.deserialize(serializedString, [ClassName1, ClassName2, ...])`. -
TypeError: instance.methodName is not a function
cause The deserialized object did not correctly retain its class methods. This often happens if the class definitions were not supplied during deserialization or were incorrect.fixVerify that all relevant class definitions are correctly imported and passed to the `deserialize` method. For example: `ESSerializer.deserialize(serializedData, [MyCustomClass]);` -
Error: Cannot deserialize circular structure without ESSerializer Pro.
cause Attempting to deserialize an object with circular references using the standard `esserializer` package.fixEither refactor your object structure to avoid circular references, or consider using 'ESSerializer Pro' which explicitly supports this feature. -
TypeError: ESSerializer.serialize is not a function
cause Incorrect import of the `ESSerializer` module, typically trying to use a named import instead of the default export in an ES module context, or vice-versa in CommonJS.fixFor ES Modules: `import ESSerializer from 'esserializer';`. For CommonJS: `const ESSerializer = require('esserializer');`.
Warnings
- breaking Versions prior to `1.3.7` contained unpatched vulnerabilities. Users should upgrade to `1.3.7` or newer immediately for security fixes.
- gotcha Advanced features like serialization of `Map`, `Set` with complex keys, `Symbol` types, and circular object structures are only available in 'ESSerializer Pro' or via specific options. The base `esserializer` package may not handle these scenarios out-of-the-box or may require manual configuration.
- gotcha When deserializing, custom classes involved in the object graph *must* be provided as the second argument to `ESSerializer.deserialize()`. Failing to do so will result in generic objects or lost methods/instanceof checks.
Install
-
npm install esserializer -
yarn add esserializer -
pnpm add esserializer
Imports
- ESSerializer
import { ESSerializer } from 'esserializer';import ESSerializer from 'esserializer';
- ESSerializer
const ESSerializer = require('esserializer'); - ESSerializer
type ESSerializerType = typeof ESSerializer;
Quickstart
import ESSerializer from 'esserializer';
class ClassC {
constructor(public value: number) {}
getDoubled(): number { return this.value * 2; }
}
class ClassB {
constructor(public name: string, public cInstance: ClassC) {}
greet(): string { return `Hello from ${this.name}! C's doubled value: ${this.cInstance.getDoubled()}`; }
}
class ClassA {
private id: string;
public date: Date;
public bInstance: ClassB;
public myArray: number[];
constructor(id: string) {
this.id = id;
this.date = new Date();
this.bInstance = new ClassB('Nested B', new ClassC(10));
this.myArray = [1, 2, 3];
}
getId(): string { return this.id; }
getDetails(): string {
return `ID: ${this.id}, Date: ${this.date.toISOString()}, B's greeting: ${this.bInstance.greet()}, Array: ${this.myArray.join(',')}`;
}
}
const originalObj = new ClassA('unique-123');
console.log('Original object details:', originalObj.getDetails());
console.log('Original object B instance greet:', originalObj.bInstance.greet());
// Serialize the object
const serializedString = ESSerializer.serialize(originalObj);
console.log('Serialized string (truncated):', serializedString.substring(0, 100) + '...');
// Deserialize the object, providing custom classes
const deserializedObj = ESSerializer.deserialize(serializedString, [ClassA, ClassB, ClassC]);
console.log('Deserialized object details:', deserializedObj.getDetails());
console.log('Deserialized object B instance greet:', deserializedObj.bInstance.greet());
// Verify instance types and methods
console.assert(deserializedObj instanceof ClassA, 'Deserialized object is not an instance of ClassA');
console.assert(deserializedObj.bInstance instanceof ClassB, 'Nested object is not an instance of ClassB');
console.assert(deserializedObj.bInstance.cInstance instanceof ClassC, 'Deeply nested object is not an instance of ClassC');
console.assert(typeof deserializedObj.getId === 'function', 'getId method missing');
console.assert(deserializedObj.getId() === 'unique-123', 'ID mismatch');
console.assert(deserializedObj.date instanceof Date, 'Date object not retained');
console.log('Serialization and deserialization successful!');