Skip to main content

set()

set<T>(object, path, value): T

Sets the value at path of object, returning a new object (immutable).

WHY WRAPPING NATIVE?

We prefer to wrap this method to ensure Immutability and safe property access. See Design Philosophy

note

Creates intermediate objects/arrays as needed based on path structure.


Type Parameters​

T: T = any​

The type of the input object.


Parameters​

object: T​

The object to set the value in.

path: string | symbol | (string | number | symbol)[]​

Property path (dot notation string, symbol, or array of keys).

value: any​

The value to set.


Returns: T​

A new object with the value set at the specified path.


See Also​

get


Since​

2.0.0


Note​

Uses structuredClone for performance; falls back to deepClone for symbol keys.


Performance​

O(n + m) time & space where n is object size, m is path length. structuredClone when possible (faster), deepClone only for symbol keys. Early returns for null/empty path.


Also known as​

assocPath (Ramda) · set (Lodash, es-toolkit, Remeda, Radashi, Modern Dash) · ❌ (Effect, Antfu)


Example​

const obj = { a: { b: { c: 3 } } };

set(obj, 'a.b.c', 42); // => { a: { b: { c: 42 } } }
set(obj, ['a', 'b', 'd'], 'new'); // => { a: { b: { c: 3, d: 'new' } } }

// Create nested structures automatically
set({}, 'user.profile.name', 'John');
// => { user: { profile: { name: 'John' } } }

// Array creation with bracket notation
set({}, 'items[0].value', 42);
// => { items: [{ value: 42 }] }

How it works?​

Immutably sets a value at a nested path, returning a new object.

Immutability​

Auto-Creation​

Creates intermediate objects/arrays as needed:

Array Creation​


Use Cases​

Update nested data safely πŸ“Œβ€‹

Set a value at a deep path, creating intermediate objects if missing. Returns a new object (immutable). Essential for reducer-like state updates.

const updatedState = set(state, 'users[0].isActive', true);

Create deep structures​

Build a deeply nested object from scratch by setting a single path on an empty object. Useful for converting flat keys to nested objects.

const obj = set({}, 'a.b.c', 'value');
// { a: { b: { c: 'value' } } }

Append to arrays​

Use numeric indices in the path to create or update array elements.

const list = set([], '[0].name', 'First');
// [{ name: 'First' }]

Update dynamic form fields by path​

Handle onChange events for deeply nested form fields using a dynamic path. The standard pattern for complex forms with nested objects (address, billing, etc.).

const [formData, setFormData] = useState({
name: "",
address: { street: "", city: "", zip: "" },
billing: { card: "", expiry: "" },
});

const handleChange = (path: string, value: string) => {
setFormData((prev) => set(prev, path, value));
};

// In JSX:
// <input onChange={(e) => handleChange("address.city", e.target.value)} />
// <input onChange={(e) => handleChange("billing.card", e.target.value)} />

Update chart configuration at a specific path​

Modify a specific chart option deep in the config tree without touching the rest. Perfect for interactive chart editors and dashboard customization.

let chartConfig = {
title: { text: "Revenue" },
xAxis: { type: "category", labels: { rotation: 0 } },
series: [{ data: [10, 20, 30] }],
};

// User rotates x-axis labels
chartConfig = set(chartConfig, "xAxis.labels.rotation", -45);

// User changes title
chartConfig = set(chartConfig, "title.text", "Monthly Revenue");

renderChart(chartConfig);

Update tree node expanded state by path​

Toggle a tree node's expanded state using its path in the tree structure. Essential for tree components with expand/collapse functionality.

let treeState = {
root: {
expanded: true,
children: {
src: { expanded: false, children: {} },
tests: { expanded: false, children: {} },
},
},
};

const toggleNode = (path: string) => {
const currentExpanded = get(treeState, `${path}.expanded`, false);
treeState = set(treeState, `${path}.expanded`, !currentExpanded);
renderTree(treeState);
};

toggleNode("root.children.src");
// => src node is now expanded

Update stepper step status​

Mark a step as completed in a multi-step wizard state. Perfect for stepper components tracking progress through a workflow.

let wizardState = {
steps: [
{ label: "Account", status: "current" },
{ label: "Profile", status: "pending" },
{ label: "Review", status: "pending" },
],
};

const completeStep = (stepIndex: number) => {
wizardState = set(wizardState, `steps[${stepIndex}].status`, "completed");
if (stepIndex + 1 < wizardState.steps.length) {
wizardState = set(wizardState, `steps[${stepIndex + 1}].status`, "current");
}
renderStepper(wizardState);
};

completeStep(0);
// => Step 0 is "completed", Step 1 is "current"

Build analytics event payloads dynamically​

Construct nested analytics payloads from flat user interaction data. Essential for tracking systems with structured event schemas.

let event = {};
event = set(event, "action", "purchase");
event = set(event, "metadata.product.id", "SKU-42");
event = set(event, "metadata.product.price", 29.99);
event = set(event, "metadata.user.segment", "premium");

analytics.track(event);
// => { action: "purchase", metadata: { product: { id: "SKU-42", price: 29.99 }, user: { segment: "premium" } } }