Skip to main content

cloneLite

Creates a lightweight deep clone of simple data structures with maximum performance. Performs high-speed deep cloning optimized for simple structures consisting only of primitives, plain objects, and arrays. Trades comprehensive type support for significant performance gains by eliminating circular reference tracking, type checking overhead, and specialized handlers.

Signature

const cloneLite: <Type>(target: Type, maxDepth?: number) => Type

Parameters

NameTypeDescription
target-The value to create a lightweight clone of
maxDepth-Optional maximum depth to clone (objects beyond this depth are returned as references)

Returns

A new deep clone with identical structure and values

Examples

Basic usage with simple structures

import { cloneLite } from '@winglet/common-utils';

// Primitives (returned as-is)
console.log(cloneLite(42)); // 42
console.log(cloneLite('hello')); // 'hello'
console.log(cloneLite(true)); // true

// Simple objects and arrays
const original = {
name: 'user',
scores: [95, 87, 92],
metadata: { level: 3, active: true }
};
const cloned = cloneLite(original);
cloned.scores[0] = 100;
console.log(original.scores[0]); // 95 (unchanged)
console.log(cloned.scores[0]); // 100

Nested structure cloning

const config = {
server: {
host: 'localhost',
port: 3000,
routes: ['/api', '/admin', '/public']
},
features: {
auth: { enabled: true, providers: ['google', 'github'] },
cache: { enabled: false, ttl: 3600 }
}
};

const clonedConfig = cloneLite(config);
clonedConfig.server.port = 4000;
clonedConfig.features.auth.providers.push('microsoft');

console.log(config.server.port); // 3000 (unchanged)
console.log(config.features.auth.providers); // ['google', 'github'] (unchanged)

Array with mixed simple types

const data = [
42,
'text',
{ id: 1, values: [1, 2, 3] },
[true, false, null, undefined],
{ nested: { deep: { value: 'found' } } }
];

const clonedData = cloneLite(data);
console.log(clonedData[2] !== data[2]); // true (different reference)
console.log(clonedData[4].nested !== data[4].nested); // true

Using maxDepth to limit cloning depth for performance

const deepStructure = {
config: {
database: {
connection: {
pool: {
settings: {
max: 100,
min: 10,
timeout: 30000
}
}
}
}
}
};

// Clone only first 3 levels for better performance
const partialClone = cloneLite(deepStructure, 3);
console.log(partialClone.config !== deepStructure.config); // true (cloned)
console.log(partialClone.config.database !== deepStructure.config.database); // true (cloned)
console.log(partialClone.config.database.connection !== deepStructure.config.database.connection); // true (cloned)
console.log(partialClone.config.database.connection.pool === deepStructure.config.database.connection.pool); // true (reference)

// Useful for creating shallow snapshots of deep structures
const snapshot = cloneLite(complexState, 2); // Only clone top 2 levels

Performance comparison scenarios

import { clone, cloneLite } from '@winglet/common-utils';

// Large simple dataset - cloneLite is ~5-10x faster
const simpleData = {
users: Array.from({ length: 10000 }, (_, i) => ({
id: i,
name: `user_${i}`,
active: i % 2 === 0,
scores: [Math.random() * 100, Math.random() * 100]
}))
};

// ✅ Use cloneLite for simple structures
const fast = cloneLite(simpleData); // ~2ms

// ❌ Avoid clone for simple structures (unnecessary overhead)
const slow = clone(simpleData); // ~15ms

Playground

import { cloneLite } from '@winglet/common-utils';

// Primitives (returned as-is)
console.log(cloneLite(42)); // 42
console.log(cloneLite('hello')); // 'hello'
console.log(cloneLite(true)); // true

// Simple objects and arrays
const original = {
name: 'user',
scores: [95, 87, 92],
metadata: { level: 3, active: true }
};
const cloned = cloneLite(original);
cloned.scores[0] = 100;
console.log(original.scores[0]); // 95 (unchanged)
console.log(cloned.scores[0]); // 100

Notes

Supported Types (✅):

  • Primitives: string, number, boolean, null, undefined, symbol, bigint
  • Arrays: Standard arrays with any depth of nesting
  • Plain Objects: Objects created via object literal or Object.create(null)
  • Mixed Nesting: Any combination of the above types

Unsupported Types (❌):

  • Built-in Objects: Date, RegExp, Map, Set, Error (returned as-is)
  • Binary Data: TypedArrays, ArrayBuffer, Blob, File (returned as-is)
  • Special Objects: DOM nodes, class instances, functions (returned as-is)
  • Circular References: Will cause stack overflow
  • Symbol Properties: Not copied

Performance Characteristics:

  • Speed: ~5-10x faster than clone for simple structures
  • Memory: Minimal overhead, no caching or tracking
  • Algorithm: Direct recursive copying without checks
  • Time Complexity: O(n) where n is total properties/elements
  • Space Complexity: O(d) where d is maximum depth

When to Use cloneLite:

  • JSON-serializable data structures
  • Configuration objects
  • State management for simple data
  • High-frequency cloning operations
  • Performance-critical paths
  • Data known to be simple at compile time

When to Use clone Instead:

  • Unknown or dynamic data types
  • Data with Date, RegExp, Map, Set objects
  • Possible circular references
  • Class instances with prototypes
  • Binary data or file handling
  • Need for symbol property preservation

Implementation Details:

  • No Circular Detection: Direct recursion without Map-based tracking
  • Type Checking: Only isArray and isPlainObject checks
  • Property Copying: Simple for-in loop for objects, indexed loop for arrays
  • Sparse Array Support: Preserves array holes via in operator check

Performance Benchmarks (Node.js v18, typical hardware):

  • Small objects (< 100 props): ~0.02ms (vs clone: ~0.1ms)
  • Medium objects (< 1000 props): ~0.3ms (vs clone: ~2ms)
  • Large objects (< 10000 props): ~3ms (vs clone: ~25ms)
  • Deeply nested (10 levels): ~0.5ms (vs clone: ~3ms)
  • vs JSON.parse(JSON.stringify): ~1.5x faster, handles undefined
  • vs structuredClone: ~3x faster but less type support

Safety Considerations:

  • Stack Overflow Risk: Deep nesting (>10000 levels) or circular refs
  • Type Loss: Complex types become plain objects or are skipped
  • Prototype Loss: Class instances lose methods and inheritance
  • Reference Sharing: Unsupported types share references with original

Migration Path:

// Before: Using clone for everything
const cloned = clone(data); // Slow for simple data

// After: Choose based on data type
const cloned = isSimpleData(data)
? cloneLite(data) // Fast path for simple data
: clone(data); // Full support for complex data