nanoclone
nanoclone is a minimalist JavaScript utility designed for deep cloning objects, weighing in at approximately 300 bytes. As of version 1.0.2, it provides a highly efficient solution for creating independent copies of various data structures, including primitives, arrays, plain objects, DOM Nodes, Date and RegExp instances, as well as Maps and Sets. A key differentiator is its ability to handle circular structures without falling into infinite loops. The library focuses on performance and a small footprint, offering a viable alternative to larger cloning libraries, especially in performance-sensitive or size-constrained environments. While its release cadence isn't explicitly defined, its small and focused scope suggests updates are primarily for bug fixes or minor enhancements. It ships with TypeScript types, enhancing developer experience in TypeScript projects.
Common errors
-
Maximum call stack size exceeded
cause Attempting to clone an extremely deep object structure or a very complex, recursive object graph that exhausts the JavaScript engine's call stack during the recursive cloning process.fixReduce the depth of the object being cloned, or consider custom cloning logic to manage recursion. While `nanoclone` handles circular structures, extreme depth can still be problematic. -
Cloned object of type X does not behave as expected or is empty
cause `nanoclone` does not provide full deep cloning support for all possible JavaScript object types beyond its explicitly listed supported types (e.g., WeakMap, Promises, custom class instances). For these types, it might perform a shallow copy, return an empty object, or fail to preserve their internal state.fixReview the 'Supported' list in `nanoclone`'s documentation. If you need to clone unsupported types, you may need to implement custom serialization/deserialization for those specific parts of your object or use a different cloning library that offers broader type support.
Warnings
- gotcha nanoclone provides deep cloning for primitives, arrays, plain objects, Date, RegExp, Map, Set, and DOM Nodes. However, it does not explicitly support or correctly clone all complex built-in JavaScript objects (e.g., WeakMap, WeakSet, ArrayBuffer, TypedArrays, Promise, Error instances) or instances of user-defined classes. These types may be shallow copied, return an empty object, or not preserve internal state.
- gotcha While nanoclone handles circular references, deep cloning can be computationally intensive for extremely large, deeply nested, or highly interconnected objects. This can impact performance or potentially lead to 'Maximum call stack size exceeded' errors in environments with limited stack sizes.
- gotcha Functions and Symbols are copied by reference, not deeply cloned. This is standard behavior for deep cloning libraries as cloning executable code or unique symbols is complex and rarely desired. Any functions or symbols within the object will point to the same original reference.
Install
-
npm install nanoclone -
yarn add nanoclone -
pnpm add nanoclone
Imports
- clone
import { clone } from 'nanoclone'import clone from 'nanoclone'
- clone
const { clone } = require('nanoclone')const clone = require('nanoclone') - clone (TypeScript type)
import type clone from 'nanoclone'
Quickstart
import clone from 'nanoclone';
interface DeepObject {
num: number;
arr: number[];
nested: {
obj: {
a: number;
};
};
d?: Date;
}
let a: DeepObject = {
num: 2,
arr: [1, 2, 3],
nested: {
obj: {
a: 0
}
},
d: new Date()
};
let b: DeepObject = clone(a);
// Verify independence
a.num = 10; // Change original
b.nested.obj.a = 5; // Change clone
a.d?.setFullYear(2000); // Change original Date
console.log('Original object:', a);
// Expected: { num: 10, arr: [1, 2, 3], nested: { obj: { a: 0 } }, d: Date(2000...) }
console.log('Cloned object:', b);
// Expected: { num: 2, arr: [1, 2, 3], nested: { obj: { a: 5 } }, d: Date(current year...) }