Blazingly fast and fully typed deep copy utility for JSON-compatible data structures.
-
High Performance
Outperforms popular libraries likeklona/json,lodash.cloneDeepand even copying using the nativeJSON.parseorstructuredClonemethod. -
Type-Safe
Fully typed with TypeScript declarations.
# npm / node
npm install jsoncpy
# jsr / deno
deno add @observ33r/jsoncpy
# bun
bun install jsoncpyimport jsoncpy from 'jsoncpy';
export type JSONCpyValue =
| number
| string
| boolean
| null
| JSONCpyArray
| JSONCpyObject;
export type JSONCpyArray = JSONCpyValue[];
export interface JSONCpyObject {
[key: string]:
| JSONCpyValue
| undefined
}
/**
* Recursively creates a deep copy of a JSON-compatible value.
*
* This function supports only the following value types:
* number, string, boolean, null, arrays, and plain objects (no functions, symbols, etc.).
*
* @param source - The input value to deeply copy.
* @returns A deep copy of the input value.
*/
export default function jsoncpy(source: JSONCpyValue): JSONCpyValueimport jsoncpy from 'jsoncpy';
const source = JSON.parse('{ "a": 1, "b": ['2', null, false] }');
console.log(jsoncpy(source));{ a: 1, b: ['2', null, false] }Big JSON Object (~1.2 MiB, deeply nested)
| Library | Time | Relative Speed |
|---|---|---|
| jsoncpy | 677.72 µs | 1.00x (baseline) |
| klona/json | 842.93 µs | 1.24x slower |
| JSON.parse | 5.02 ms | 7.41x slower |
| structuredClone | 5.18 ms | 7.64x slower |
| lodash.cloneDeep | 6.30 ms | 9.3x slower |
Full benchmark result with hardware counters
clk: ~3.62 GHz
cpu: AMD Ryzen 5 3600 6-Core Processor
runtime: node 24.4.1 (x64-linux)
benchmark avg (min … max) p75 / p99 (min … top 1%)
------------------------------------------- -------------------------------
• Big JSON Object (~1.2 MiB, deeply nested)
------------------------------------------- -------------------------------
jsoncpy 677.72 µs/iter 667.75 µs █
(616.47 µs … 1.24 ms) 1.09 ms ▇█
(181.60 kb … 802.63 kb) 570.57 kb ▇██▃▂▂▂▂▂▁▂▁▁▁▁▁▁▁▁▁▁
2.98 ipc ( 89.95% cache) 8.21k branch misses
2.61M cycles 7.80M instructions 143.89k c-refs 14.47k c-misses
klona/json 842.93 µs/iter 819.22 µs █▄
(759.86 µs … 1.34 ms) 1.29 ms ██
(370.55 kb … 575.42 kb) 570.39 kb ▃██▄▃▂▂▂▂▂▂▁▁▁▁▁▁▁▂▁▁
2.79 ipc ( 89.96% cache) 9.98k branch misses
3.22M cycles 8.98M instructions 146.66k c-refs 14.72k c-misses
lodash.cloneDeep 6.30 ms/iter 6.35 ms █▅
(5.95 ms … 8.46 ms) 7.59 ms ██
( 2.63 mb … 6.30 mb) 4.96 mb ▆██▄▄▅▂▂▂▂▂▂▂▄▃▁▂▁▁▁▂
2.28 ipc ( 95.88% cache) 44.84k branch misses
23.53M cycles 53.57M instructions 2.46M c-refs 101.33k c-misses
JSON.parse 5.02 ms/iter 5.11 ms █
(4.62 ms … 7.01 ms) 5.97 ms ▄█▆▃▃
( 1.53 mb … 1.54 mb) 1.53 mb ▂███████▃▅▆▄▃▁▂▃▂▁▁▄▃
2.51 ipc ( 88.98% cache) 88.40k branch misses
17.95M cycles 45.04M instructions 454.77k c-refs 50.12k c-misses
structuredClone 5.18 ms/iter 5.16 ms █▂
(5.08 ms … 6.15 ms) 5.72 ms ▃██
( 1.75 mb … 1.79 mb) 1.75 mb ███▆▄▂▂▃▁▂▂▂▁▁▁▁▂▂▂▁▂
2.49 ipc ( 93.15% cache) 68.73k branch misses
19.95M cycles 49.73M instructions 718.22k c-refs 49.18k c-misses
summary
jsoncpy
1.24x faster than klona/json
7.41x faster than JSON.parse
7.64x faster than structuredClone
9.3x faster than lodash.cloneDeepBenchmark uses mitata to test performance with big JSON object to reflect a realistic real-world scenario.
You can run bechmark with:
npm run benchmarkThis package uses rollup to generate clean and optimized ESM/CJS builds.
To build package from source code, run:
npm run buildThis will generate the output in the dist/ folder. Builds are handled via custom rollup config and exposed under appropriate exports in package.json.
All tests are written in Vitest with native ESM support and zero transform overhead.
You can run the full suite with:
npm testIf you find this project useful, you can support it with a one-time donation over PayPal. Thank you!
Feel free to open issues or submit pull requests on GitHub.
This project is licensed under the MIT License.