@produck/json-copier
v1.0.3
Published
A utility to deep copy JSON-compatible values.
Readme
@produck/json-copier
A tiny utility to deep copy JSON-compatible values.
Installation
npm install @produck/json-copierUsage
import { copy } from "@produck/json-copier";
const value = {
name: "demo",
items: [1, 2, { ok: true }],
meta: { count: 3 },
};
const cloned = copy(value);
console.log(cloned); // same structure
console.log(cloned === value); // false
console.log(cloned.items === value.items); // false
console.log(cloned.meta === value.meta); // falseAPI
copy(value: JsonValue): JsonValue
Deep copy a JSON-compatible value.
- Primitive values (
null,boolean,number,string) are returned as-is. - Arrays are copied recursively.
- Objects are copied recursively.
Input Contract
copy is designed for JSON-compatible input only.
- Supported input types:
null,boolean,number,string,Array, and plain JSON objects. - This package does NOT perform runtime validation for unsupported types.
Where Valid JSON Objects Come From
In practice, inputs passed to copy commonly come from one of these
trusted sources:
Fully validated runtime objects
Objects that have already gone through sufficient runtime checks (for example, schema validation, guard functions, or strict data sanitization) and are known to be JSON-compatible.
Standard JSON-producing pipelines
Data produced by methods that return standard JSON objects, such as
JSON.parse(...)and processing chains built on top of its result.
Undefined-but-Compatible Scenarios
Because copy does not validate input at runtime, certain non-JSON
values happen to produce usable results with the current implementation.
These behaviors are not part of the public contract and may change
without notice. They are documented here only for awareness.
undefined— Returned as-is.typeofis not"object", so it is treated as a primitive.NaN/Infinity/-Infinity— Returned as-is.typeofis"number", so they pass the primitive check.BigIntvalue — Returned as-is.typeofis"bigint", so it passes the primitive check.function— Returned by reference.typeofis"function", so it passes the primitive check.Symbol— Returned as-is.typeofis"symbol", so it passes the primitive check.Object with inherited enumerable properties — Inherited properties are copied into the result as own properties.
for...intraverses the entire prototype chain.
Recommendation: Do not rely on these behaviors. If your data may contain non-JSON types, validate or transform it before passing it to
copy, or usestructuredCloneinstead.
Benchmark
To compare performance with the native structuredClone, a benchmark was run
using a moderately complex JSON object and 10,000 iterations for each method.
Test data overview:
The benchmark object contains a flat section (name, items, meta) and a
deep array of 1,000 elements. Each element is a small object with a nested
array containing two numbers and one object, resulting in roughly 4,000+
nested values per copy operation.
Benchmark source (test/benchmark.mjs):
import { copy } from '../src/index.mjs';
const obj = {
name: 'demo',
items: [1, 2, { ok: true }],
meta: { count: 3 },
deep: Array.from({ length: 1000 }, (_, i) => ({
n: i,
arr: [i, i + 1, { v: i }],
})),
};
const iterations = 10000;
console.log('Benchmark: copy vs structuredClone');
console.time('copy');
for (let i = 0; i < iterations; i++) {
copy(obj);
}
console.timeEnd('copy');
console.time('structuredClone');
for (let i = 0; i < iterations; i++) {
structuredClone(obj);
}
console.timeEnd('structuredClone');Result (Node.js 18+, Windows):
Benchmark: copy vs structuredClone
copy: ~857ms
structuredClone: ~9.5sConclusion:
For pure JSON data, copy is significantly faster than structuredClone
(about 10x in this scenario). If you only need to handle JSON-compatible values,
this package is a lightweight and high-performance choice.
Note:
structuredCloneis a built-in API that supports a much wider range of types, includingDate,RegExp,Map,Set,ArrayBuffer,Blob, and objects with circular references. If your data includes any of these types,structuredCloneis the appropriate choice. This package is designed exclusively for JSON-compatible data, where its simplicity and performance are the primary advantages.
License
MIT
