klona - Deep Cloning Utility
klona is a minimalist, high-performance utility for deep cloning JavaScript objects, arrays, dates, regexps, and other complex data types. Currently stable at version 2.0.6, it maintains a regular release cadence with frequent patches and minor improvements, as seen with multiple patch releases since v2.0.0. Its primary differentiator lies in its tiny footprint (ranging from 240B for `klona/json` to 501B for `klona/full` gzipped) and superior speed compared to many alternatives. It offers multiple "modes" (`klona/json`, `klona/lite`, `klona`, `klona/full`), allowing developers to import only the necessary functionality for specific data type support, thereby optimizing bundle size. It supports ESM, CommonJS, and UMD, and ships with TypeScript types.
Common errors
-
TypeError: klona is not a function
cause Attempting to use `klona` as a default import/require after the v2.0.0 breaking change to named exports.fixFor ESM, change `import klona from 'klona'` to `import { klona } from 'klona'`. For CommonJS, change `const klona = require('klona')` to `const { klona } = require('klona')`. -
Type error: Module ''klona'' has no exported member 'klona'. Did you mean to use 'import klona from 'klona'' instead?
cause Using an older TypeScript version or configuration with a `klona` version >=2.0.0, where the type definitions might be misinterpreted, or the editor cache is stale.fixEnsure your TypeScript version and configuration (`moduleResolution`) are compatible. Clear your editor's TypeScript cache if using VSCode. The correct import for v2+ is `import { klona } from 'klona'`.
Warnings
- breaking Starting with v2.0.0, `klona` migrated from a default export to a named export. This affects both ESM `import` statements and CommonJS `require` calls.
- gotcha Prior to v2.0.5, `klona` and `klona/lite` had an issue where `Object.assign` within class constructors was not handled correctly during cloning, potentially leading to incorrect copies for custom class instances.
- gotcha In `klona/full`, prototype methods were not consistently copied prior to v2.0.4, which could lead to incomplete deep clones for objects with prototype chains.
- gotcha Versions prior to v1.1.1 had issues correctly handling `Set` and `Map` instances during cloning, and lacked explicit protection against `__proto__` pollution attacks.
- gotcha TypeScript users leveraging `moduleResolution: 'nodenext'` in their `tsconfig.json` might encounter type resolution issues with `klona` in versions prior to v2.0.6 due to missing 'types' condition in the package's `exports` map.
Install
-
npm install klona -
yarn add klona -
pnpm add klona
Imports
- klona
import klona from 'klona';
import { klona } from 'klona'; - klona (JSON mode)
import klona from 'klona/json';
import { klona } from 'klona/json'; - klona (Full mode)
import klona from 'klona/full';
import { klona } from 'klona/full'; - klona (CommonJS)
const klona = require('klona');const { klona } = require('klona');
Quickstart
import { klona } from 'klona';
const input = {
foo: 1,
bar: {
baz: 2,
bat: {
hello: 'world'
}
},
date: new Date(),
regex: /test/g,
items: new Set([1, 2, 3]),
mapData: new Map([['a', 1], ['b', 2]])
};
const output = klona(input);
// Verify deep equality (requires an assertion library like Node's assert.deepStrictEqual)
// import * as assert from 'assert';
// assert.deepStrictEqual(input, output);
// Modifying the clone does not affect the original
output.bar.bat.hola = 'mundo';
output.bar.baz = 99;
output.items.add(4);
output.date.setFullYear(2030);
console.log('Original Input:', JSON.stringify(input, null, 2));
console.log('Cloned Output (modified):', JSON.stringify(output, null, 2));
// You would see 'hola' and 'mundo' only in the output, and 'baz' will be 99.
// The date and set will also reflect the changes only in the output.