rotem-horovitz
    _hello_about-me_blog_snippets_projects_games
find me in:
privacy
← Back to snippets

deep-clone

Recursively copy plain objects and arrays so nested mutations don't leak back to the source.

May 20, 2026
utilityimmutability

A minimal recursive deep clone for plain JSON-shaped values: primitives, arrays, and plain objects. The implementation walks the structure with Object.entries and map, producing fresh containers at every level.

export function deepClone<T>(value: T): T {
	if (value === null || typeof value !== 'object') return value;
	if (Array.isArray(value)) return value.map(deepClone) as T;
	return Object.fromEntries(
		Object.entries(value as Record<string, unknown>).map(([key, val]) => [
			key,
			deepClone(val),
		]),
	) as T;
}

Caveats

  • Doesn't handle Date, Map, Set, RegExp, class instances, or circular references. For those, use structuredClone (when available in your target runtime) or a battle-tested library.
  • Keys with undefined values survive the round-trip — unlike a JSON.parse(JSON.stringify(...)) approach which would strip them.