ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 55

  1. Blog

Klona vs structuredClone: 1.4M vs 225k Clones per Second

Aditya Challa·5 October 2026·5 min read

Hands-on
On this page
  1. What I tested
  2. How much bundle does klona add?
  3. Is klona faster than structuredClone?
  4. What does each one lose or break?
  5. Which one should you pick?
  6. Sources
  7. Related

I timed deep clones on this box: klona 2.0.6 copied a small app-state object about 1.4–1.5 million times per second, while the built-in structuredClone managed about 225,000. That is roughly 6.5× faster, for 477 B gzip of extra bundle that structuredClone does not cost you.

Short answer: use structuredClone by default, since it is free, handles circular references, and covers Date, Map, Set and typed arrays. Reach for klona in hot paths (reducers, undo stacks, per-request config copies) or when you need class instances to keep their prototype. No affiliate links in this post.

What I tested

  • Machine: 8 vCPU Intel Xeon / 15 GB RAM shared Linux cloud box, tested 6 Oct 2026 about 01:14 IST.
  • Versions: klona 2.0.6 (default, klona/json, klona/lite, klona/full), Node 22.20.0 built-in structuredClone, JSON.parse(JSON.stringify()) as a baseline, esbuild 0.28.2 browser ESM minify + gzip -9.
  • Fixture: /workspace/bench-klona-structuredclone/. Small payload: a 4-key app-state object with nested arrays and one Date, cloned 100,000 times. Large payload: 284 seo.json objects from my drafts folder (505 KB as JSON), cloned 50 times. 9 rounds, median, after warm-up. I ran it twice with the order reversed.
  • Findings: small object, 1.42M and 1.50M ops/s for klona vs 227k and 224k for structuredClone. Large payload, 50 clones took 8.4 and 5.7 ms with klona vs 36.0 and 35.0 ms with structuredClone. All five methods I timed (klona/lite included) produced JSON-identical copies of the large payload. klona/lite landed between klona and klona/json (1.59M and 1.61M ops/s on the small object), so I left it out of the table below.
  • One surprise: klona/json did not clone a Date, Map, Set, RegExp or typed array. It handed back the same object, so a later mutation would leak into the original. Only use it for plain JSON data.
  • Not tested: browsers, Bun or Deno, Web Worker postMessage, very deep nesting, objects with getters or symbol keys, and memory use.

How much bundle does klona add?

Build (esbuild browser minify)Minifiedgzip -9
klona/json398 B268 B
klona/lite641 B378 B
klona (default)923 B477 B
klona/full1,059 B518 B
structuredClone (built in)54 B74 B

The structuredClone row is just my one-line test entry; the function itself ships with the runtime. If you watch every byte, size-limit vs bundlesize will flag the 0.3–0.5 KB.

Is klona faster than structuredClone?

Payload (median of 9)klonaklona/jsonstructuredCloneJSON round-trip
small object, run 11.42M ops/s2.06M ops/s227k ops/s213k ops/s
small object, run 21.50M ops/s2.06M ops/s224k ops/s213k ops/s
505 KB payload x 50, run 18.4 ms7.2 ms36.0 ms92.8 ms
505 KB payload x 50, run 25.7 ms4.1 ms35.0 ms148.5 ms

Yes, by a wide margin on this box. structuredClone pays for a serialize and deserialize step on every call. That cost barely matters for one clone per click, but it adds up in a store that copies state on every update. My Immer vs Mutative and Zustand vs Redux Toolkit posts cover the case where you can avoid deep copies altogether, and Jotai vs Zustand compares two small stores built on immutable updates.

What does each one lose or break?

Value inside the objectklonaklona/jsonstructuredCloneJSON round-trip
Date, Map, Set, RegExpclonedsame referenceclonedlost
Typed arrayclonedsame referenceclonedlost
Class instanceprototype keptlostbecomes plain objectlost
Functionsame referencesame referencethrows DataCloneErrordropped
undefined valuekeptkeptkeptdropped
Circular referencethrows RangeErrorthrows RangeErrorclonedthrows TypeError

This table matters more than the speed one. structuredClone is the only option here that survived a circular object. klona is the only one that kept a class instance working, with its methods still callable after the copy.

Which one should you pick?

SituationMy pick
Occasional copy of form data or API JSONstructuredClone
Data that may contain circular referencesstructuredClone
Store or undo stack cloning on every changeklona
Objects that must keep their class methodsklona
Hot path on plain JSON onlyklona/json

Bottom line: klona ran about 6.5× faster than structuredClone on small objects and about 4–6× faster on a 505 KB payload, for 477 B gzip. Who should not add it: apps that clone a few times per user action. The built-in is fast enough there, costs zero bytes, and handles cycles. If you are already trimming utility deps, compare notes with es-toolkit vs lodash.

How this was made: I installed klona on the ShopperCove box, measured esbuild minify+gzip sizes for each entry point, timed small and large clones in two order-reversed runs, ran a type-behavior check across Date, Map, Set, class, function and circular inputs, and saved the JSON results. The write-up was drafted with AI help and checked against that output.

Sources

  • https://github.com/lukeed/klona
  • https://www.npmjs.com/package/klona
  • https://developer.mozilla.org/en-US/docs/Web/API/Window/structuredClone
  • https://nodejs.org/api/globals.html

Related

  • https://www.shoppercove.com/blog/size-limit-vs-bundlesize
  • https://www.shoppercove.com/blog/immer-vs-mutative
  • https://www.shoppercove.com/blog/zustand-vs-redux-toolkit
  • https://www.shoppercove.com/blog/es-toolkit-vs-lodash
  • https://www.shoppercove.com/blog/jotai-vs-zustand
  • https://www.shoppercove.com/blog/zod-vs-valibot
  • https://www.shoppercove.com/blog/tanstack-query-vs-swr
  • https://www.shoppercove.com/blog/dayjs-vs-date-fns
klonastructuredclonejavascriptperformancebenchmarkingdeep cloningnode.jsbundle size

Lab evidence

What I found running this

Hands-on on ShopperCove box 6 Oct 2026 ~01:14 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 22.20.0). klona 2.0.6 (default, klona/json, klona/lite, klona/full) vs built-in structuredClone vs JSON.parse(JSON.stringify()), esbuild 0.28.2 browser ESM minify + gzip -9. Fixture /workspace/bench-klona-structuredclone/. Size gzip: klona 477 B, json 268, lite 378, full 518. Speed (9 rounds median, run twice with order reversed): small 4-key state object with a Date x 100,000 -> klona 1,423,933 / 1,502,413 ops/s, klona/json 2.06M, klona/lite 1.61M / 1.59M, structuredClone 227,278 / 224,234, JSON 212,842 / 212,607. 284 seo.json objects (505,296 B JSON) x 50 -> klona 8.418 / 5.691 ms, structuredClone 36.004 / 34.961 ms, JSON 92.779 / 148.538 ms. All copies JSON-identical. Behavior (res-behavior.json): structuredClone clones circular refs, drops class prototype, throws DataCloneError on functions; klona keeps class prototype, shares function refs, throws RangeError on circular; klona/json returns Date/Map/Set/RegExp/typed arrays by same reference. Not tested: browsers, Bun/Deno, postMessage, getters/symbols, memory. No affiliate.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 91

    Tinyexec vs execa: 2.7 KB vs 37 KB Gzip

    5 Oct 2026

  • Plate 48

    Zod vs Valibot: 1.14M vs 0.97M Parses

    zod 4.6.5 vs valibot 1.5.0 on one nested user schema (uuid/email/age/tags/profile/enum). Warm medians after 2k warmup + 9×50k: zod.parse 1,144,494 ops/s vs valibot.parse 968,187 (~1.18×). safeParse fail: valibot 697,760 vs zod 415,523 (~1.7×). esbuild minify+gzip9: 452,999/92,636 B vs 85,126/15,422 B. Package trees ~6.1 MB vs ~1.9 MB. Fixture /workspace/bench-zod-valibot/.

    5 Oct 2026

  • Plate 78

    Clsx vs classnames: 294 B vs 857 B Gzip

    5 Oct 2026

On this page

  1. What I tested
  2. How much bundle does klona add?
  3. Is klona faster than structuredClone?
  4. What does each one lose or break?
  5. Which one should you pick?
  6. Sources
  7. Related
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove