Object Serialization in JavaScript (Node.js): From JSON to Binary Formats
Serialization is the process of converting a complex data structure (object, array, Map, Set) into a format that can be saved to a file, transmitted over a network, or sent to another process. In Node.js, serialization is used everywhere: from REST APIs to inter-process communication and caching. In this article, we will cover the main tools and libraries for serialization in the Node.js environment, their strengths and weaknesses.
1. Built-in JSON: The De Facto Standard
The simplest and most popular way is to use the global JSON object with the JSON.stringify() and JSON.parse() methods. It is natively supported in Node.js without installing additional packages.
Basic Serialization Example:
const user = { name: 'Alexey', age: 30, roles: ['admin', 'editor'], metadata: null};
// Serialize to stringconst jsonString = JSON.stringify(user);console.log(jsonString);// {"name":"Alexey","age":30,"roles":["admin","editor"],"metadata":null}
// Deserialize back to objectconst parsedUser = JSON.parse(jsonString);console.log(parsedUser.name); // AlexeyJSON Limitations:
- Does not support functions — object methods will be removed.
- Does not support circular references — will throw a
Converting circular structure to JSONerror. - Ignores undefined, Symbol, BigInt (the latter throws an error).
- Converts Date to a string — the Date object is not restored upon deserialization.
Custom Serialization with replacer:
const data = { name: 'Test', date: new Date(), secret: 'do not save', nested: { value: 42 }};
const json = JSON.stringify(data, (key, value) => { if (key === 'secret') return undefined; // exclude the field if (value instanceof Date) return value.toISOString(); // explicitly format the date return value;}, 2); // formatting with indentation
console.log(json);2. Serialization via Buffer: For Binary Data
When you need to transmit binary data (images, files, protobuf), the Buffer class is used. In Node.js, Buffer allows converting strings and objects to binary format and back.
Example with Buffer and JSON:
const obj = { message: 'Hello, world!' };
// Serialize to JSON, then to Bufferconst buffer = Buffer.from(JSON.stringify(obj), 'utf-8');console.log(buffer); // <Buffer 7b 22 6d 65 73 73 61 67 65 22 3a 22 d0 9f ...
// Back againconst restored = JSON.parse(buffer.toString('utf-8'));console.log(restored.message); // Hello, world!Direct Number Serialization into Buffer:
const buf = Buffer.alloc(8);buf.writeInt32LE(255, 0); // write a 32-bit integerbuf.writeFloatLE(3.14, 4); // write a float
console.log(buf); // binary representation// Readingconsole.log(buf.readInt32LE(0)); // 255console.log(buf.readFloatLE(4)); // 3.1400001049041753. The flatted Library: A Solution for Circular References
If your object contains circular references (e.g., a DOM tree or a graph), standard JSON won't handle it. The flatted library (author — Andrea Giammarchi) solves this problem.
Installation and Example:
npm install flattedconst { stringify, parse } = require('flatted');
const circularObj = { name: 'Cycle' };circularObj.self = circularObj; // circular reference
const json = stringify(circularObj);console.log(json);// {"name":"Cycle","self":"$1"}
const restored = parse(json);console.log(restored.name); // Cycleconsole.log(restored.self === restored); // true