@chaisser/deep-clone
v1.0.1
Published
Fast deep clone for objects and arrays
Maintainers
Readme
📋 @chaisser/deep-clone
Fast deep and shallow clone for objects, arrays, Dates, RegExps, Maps, and Sets
✨ Features
- 🎯 Type-safe - Full TypeScript support with generics
- 🔄 Deep clone - Recursively copies nested objects, arrays, Maps, Sets, Dates, RegExps
- 📄 Shallow clone - One-level copy when you don't need recursion
- 🗺️ Map & Set - Full support for Map and Set cloning
- 📅 Date & RegExp - Properly clones Date and RegExp instances
- 🛡️ Immutable - Never mutates the original value
- 🪶 Zero dependencies - Lightweight and tree-shakeable
- 🏎️ ESM + CJS - Dual module format support
📦 Installation
npm install @chaisser/deep-clone
# or
yarn add @chaisser/deep-clone
# or
pnpm add @chaisser/deep-clone🚀 Quick Start
import { deepClone, shallowClone } from '@chaisser/deep-clone';
// Deep clone
const original = { user: { name: 'Doruk', hobbies: ['coding'] } };
const cloned = deepClone(original);
cloned.user.name = 'Alice';
cloned.user.hobbies.push('music');
console.log(original.user.name); // 'Doruk' — unchanged
console.log(original.user.hobbies); // ['coding'] — unchanged
// Shallow clone
const obj = { a: 1, b: { c: 2 } };
const shallow = shallowClone(obj);
shallow.b.c = 99;
console.log(obj.b.c); // 99 — nested objects are shared references📖 What It Does
This package provides deep and shallow cloning utilities for JavaScript values. deepClone recursively copies all nested structures — objects, arrays, Maps, Sets, Dates, and RegExps — producing a fully independent clone. shallowClone copies only the top level, keeping nested references shared with the original.
🎯 How It Works
The package provides 2 functions:
deepClone- Recursively clones any value including nested objects, arrays, Maps, Sets, Dates, and RegExpsshallowClone- Copies one level deep using spread ({...obj}) or.slice()for arrays
deepClone handles these types:
- Primitives (
null,undefined,string,number,boolean,symbol,bigint) - Plain objects
- Arrays
DateinstancesRegExpinstancesMapinstancesSetinstances
🎨 What It's Useful For
- Immutable State - Clone before mutating (Redux, state management)
- Data Isolation - Prevent shared reference bugs
- Undo/Redo - Snapshot state at a point in time
- Testing - Clone fixtures to avoid test pollution
- Configuration - Deep copy defaults before overriding
- Caching - Return clones from cache to prevent external mutation
💡 Usage Examples
Objects
import { deepClone } from '@chaisser/deep-clone';
const original = {
name: 'Doruk',
address: {
city: 'Istanbul',
coords: { lat: 41.01, lng: 28.98 },
},
};
const clone = deepClone(original);
clone.address.city = 'Ankara';
console.log(original.address.city); // 'Istanbul' — unaffectedArrays
const original = [[1, 2], [3, 4], { key: 'value' }];
const clone = deepClone(original);
clone[0].push(3);
clone[2].key = 'changed';
console.log(original[0]); // [1, 2] — unaffected
console.log(original[2].key); // 'value' — unaffectedMaps and Sets
const original = new Map([
['user', { name: 'Doruk' }],
['scores', new Set([10, 20, 30])],
]);
const clone = deepClone(original);
clone.get('user')!.name = 'Alice';
(clone.get('scores') as Set<number>).add(40);
console.log(original.get('user')!.name); // 'Doruk' — unaffected
console.log((original.get('scores') as Set<number>).has(40)); // falseDates and RegExps
const original = {
date: new Date('2024-01-01'),
pattern: /^hello\s+world$/gi,
};
const clone = deepClone(original);
clone.date.setFullYear(2025);
console.log(original.date.getFullYear()); // 2024 — unaffected
console.log(clone.pattern.source); // '^hello\\s+world$'
console.log(clone.pattern.flags); // 'gi'Primitives
deepClone(42); // 42
deepClone('hello'); // 'hello'
deepClone(null); // null
deepClone(undefined); // undefined
deepClone(true); // trueShallow Clone
import { shallowClone } from '@chaisser/deep-clone';
const original = { a: 1, nested: { b: 2 } };
const clone = shallowClone(original);
clone.a = 99;
clone.nested.b = 99;
console.log(original.a); // 1 — top level is independent
console.log(original.nested.b); // 99 — nested is shared!📚 API Reference
deepClone<T>(value: T): T
Recursively clone any value.
| Parameter | Type | Description |
|---|---|---|
| value | T | Any value to clone |
Returns: A deep, independent copy of value
Supported types:
- Primitives returned as-is (
null,undefined,string,number,boolean,symbol,bigint) - Plain objects — cloned key by key
- Arrays — mapped element by element
Date— newDatewith same timestampRegExp— newRegExpwith same source and flagsMap— cloned with recursively cloned keys and valuesSet— cloned with recursively cloned values
shallowClone<T>(value: T): T
Clone one level deep. Nested objects/arrays are shared references.
| Parameter | Type | Description |
|---|---|---|
| value | T | Any value to clone |
Returns: A shallow copy of value
🔗 Related Packages
Explore our other utility packages in the @chaisser namespace:
- @chaisser/deep-clone (this package) - Deep and shallow cloning
- @chaisser/string-wizard - Advanced string manipulation
- @chaisser/type-guard - Runtime type guards and validators
- @chaisser/uuid-v7 - Time-ordered UUID v7 generator
- @chaisser/wait-for - Promise-based wait utilities
- @chaisser/regex-humanizer - Regex to human-readable descriptions
- @chaisser/password-strength - Password strength checker
- @chaisser/human-time - Human-readable time formatting
- @chaisser/obj-path - Safe dot-notation object access
- @chaisser/debounce-throttle - Rate limiting utilities
- @chaisser/color-utils - Color conversion utilities
- @chaisser/array-group-by - Array grouping utilities
- @chaisser/merge-objects - Object merge utilities
- @chaisser/chunk-array - Array chunking functions
- @chaisser/event-emitter - Typed event emitter
🔒 License
MIT - Free to use in personal and commercial projects
👨 Developed by
Doruk Karaboncuk [email protected]
📄 Repository
- GitHub: @chaisser
- NPM: @chaisser/deep-clone
🤝 Contributing
Contributions are welcome! Feel free to:
- Report bugs
- Suggest new features
- Submit pull requests
- Improve documentation
📞 Support
For issues, questions, or suggestions, please reach out through:
- Email: [email protected]
- GitHub Issues: Create an issue
Made with ❤️ by @chaisser
