
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
A blazing fast deep object copier
import copy from "fast-copy";
import { deepEqual } from "fast-equals";
const object = {
array: [123, { deep: "value" }],
map: new Map([["foo", {}], [{ bar: "baz" }, "quz"]])
};
const copiedObject = copy(object);
console.log(copiedObject === object); // false
console.log(deepEqual(copiedObject, object)); // true
Starting in 2.0.0, you can use the isStrict option to copy the object based on strict standards, meaning:
Array object) are copiedThis is significantly slower, so you should only use this if you believe it necessary.
console.log(copy(object, { isStrict: true }));
NOTE: This option is also aliased as copy.strict.
console.log(copy.strict(object));
The maximum number of nested objects traversed before a MaxDepthExceededError is thrown. Defaults to 1000.
Because copying is recursive, a value nested more deeply than the JavaScript engine's call stack allows will exhaust the stack. The default limit sits below that threshold, so deeply-nested values fail with a descriptive, catchable error instead of a raw RangeError.
try {
copy(untrustedPayload);
} catch (error) {
if (error instanceof copy.MaxDepthExceededError) {
// `error.maxDepth` is the limit that was exceeded
}
}
MaxDepthExceededError extends RangeError, so existing handling of the native stack-exhaustion error continues to work. In legacy environments without Object.setPrototypeOf, instanceof copy.MaxDepthExceededError cannot be supported; check error.name === 'MaxDepthExceededError' or error instanceof RangeError instead.
If you copy values that are legitimately nested more deeply, raise the limit; pass Infinity to remove it entirely, in which case sufficiently-deep values will again throw a native RangeError.
console.log(copy(deeplyNestedObject, { maxDepth: 2000 }));
NOTE: The depth counts nested objects only. Primitives and values already copied (circular references) do not contribute to it.
Under the hood, fast-copy uses instanceof to determine object types, which can cause false negatives when used in combination with iframe-based objects. To handle this edge case, you can pass the realm in options, which identifies which realm the object comes from and will use that realm to drive both comparisons and constructors for the copies.
<iframe srcdoc="<script>var arr = ['foo', 'bar'];</script>"></iframe>
const iframe = document.querySelector("iframe");
const arr = iframe.contentWindow.arr;
console.log(copy(arr, { realm: iframe.contentWindow })); // ['foo', 'bar']
The following object types are deeply cloned when they are either properties on the object passed, or the object itself:
ArrayArrayBufferBlobBufferDataViewDateFloat32ArrayFloat64ArrayInt8ArrayInt16ArrayInt32ArrayMapObjectRegExpSetUint8ArrayUint8ClampedArrayUint16ArrayUint32ArrayReact componentsThe following object types are copied directly, as they are either primitives, cannot be cloned, or the common use-case implementation does not expect cloning:
AsyncFunctionBooleanErrorFunctionGeneratorFunctionNumberNullPromiseStringSymbolUndefinedWeakMapWeakSetCircular objects are supported out of the box as well. By default a cache based on WeakSet is used, but if WeakSet is not available then a standard Object fallback is used. The benchmarks quoted below are based on use of WeakSet.
Small number of properties, all values are primitives
| Operations / second | |
|---|---|
| fast-copy | 2,692,822 |
| clone | 1,420,277 |
| lodash.cloneDeep | 1,277,213 |
| fast-deepclone | 768,982 |
| ramda | 719,948 |
| fast-clone | 567,342 |
| deepclone | 509,547 |
| fast-copy (strict) | 420,804 |
Large number of properties, values are a combination of primitives and complex objects
| Operations / second | |
|---|---|
| fast-copy | 109,352 |
| fast-deepclone | 101,808 |
| ramda | 93,103 |
| deepclone | 74,270 |
| fast-clone | 49,911 |
| clone | 46,355 |
| lodash.cloneDeep | 43,900 |
| fast-copy (strict) | 33,440 |
Very large number of properties with high amount of nesting, mainly objects and arrays
| Operations / second | |
|---|---|
| fast-copy | 123 |
| fast-deepclone | 101 |
| fast-clone | 93 |
| lodash.cloneDeep | 92 |
| deepclone | 66 |
| clone | 50 |
| fast-copy (strict) | 42 |
| ramda | 5 |
Objects that deeply reference themselves
| Operations / second | |
|---|---|
| fast-copy | 1,143,074 |
| ramda | 750,430 |
| clone | 722,632 |
| lodash.cloneDeep | 580,005 |
| deepclone | 490,824 |
| fast-deepclone | 446,585 |
| fast-copy (strict) | 321,678 |
| fast-clone (not supported) | 0 |
Custom constructors, React components, etc
| Operations / second | |
|---|---|
| fast-copy | 78,422 |
| clone | 52,165 |
| lodash.cloneDeep | 39,648 |
| ramda | 32,372 |
| fast-deepclone | 27,518 |
| fast-clone | 27,495 |
| deepclone | 16,552 |
| fast-copy (strict) | 12,509 |
Standard practice, clone the repo and yarn (or npm i) to get the dependencies. The following npm scripts are available:
rolluprimraf on the dist folderbuild and build:minified scriptssrc folder (also runs on dev script)lint script, but with auto-fixerlint, test:coverage, and dist scriptsprepublishOnly and release with new versionprepublishOnly and release with new beta versionprepublishOnly and simulate a new releasedevtest foldertest with code coverage calculation via nyctest but keep persistent watcherLodash's clonedeep method provides deep cloning functionality. It is part of the larger Lodash library, which is a general utility library. Compared to fast-copy, lodash.clonedeep may be slower but is part of a well-established utility library with a wide range of functions.
The clone package offers deep cloning of objects and arrays. It is less focused on performance compared to fast-copy and does not handle some of the more complex data types that fast-copy can.
Deep-copy is another package that provides deep cloning capabilities. It is similar to fast-copy in its purpose but may not have the same performance optimizations.
The rfdc (Really Fast Deep Clone) package is a competitor to fast-copy, focusing on performance for deep cloning. It claims to be faster than other deep cloning libraries for certain use cases and is a good alternative to consider when performance is critical.
FAQs
A blazing fast deep object copier
The npm package fast-copy receives a total of 12,260,963 weekly downloads. As such, fast-copy popularity was classified as popular.
We found that fast-copy demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.