Lodash _.set() Method

Beginner
⏱️ 8 min read
📚 Updated: Jul 2026
🎯 6 Examples + 3 Try It
Object utilities

What You’ll Learn

By the end of this tutorial, you’ll use _.set() to write values at nested paths without manual object building.

01

Core syntax

_.set(object, path, value) writes at any depth.

02

Mutates object

Modifies the target in place and returns it.

03

Path formats

Dot strings, key arrays, and users[0] notation.

04

Auto-create

Missing intermediate objects are created for you.

05

set vs get

Pair writes with _.get() reads.

06

Safe patterns

When to clone first and how to avoid path collisions.

What Is _.set()?

_.set() is Lodash’s nested write helper. You pass an object, a path, and a value; Lodash walks (or creates) the path and assigns the value at the end. It is the write counterpart to _.get() and pairs naturally with _.result() for read/invoke operations.

💡
Unlike _.omit() or _.pick()

_.set() mutates the object you pass in. If you need an immutable update, clone first or build on a fresh object.

Use it for user profiles, configuration trees, form state patches, and any time you would otherwise write fragile chains like obj.a = obj.a || {}; obj.a.b = value.

📝 Syntax

The signature is three arguments—object, path, and value:

javascript
_.set(object, path, value)

Syntax Rules

  • object — the object to modify (mutated in place).
  • path — dot string ("profile.name"), array (["profile", "name"]), or bracket form ("users[0].name").
  • value — any JavaScript value to assign at the resolved location.
  • Return value — the same object reference (for chaining).
  • Missing segments — Lodash creates plain objects or array slots as needed.
javascript
import set from "lodash/set";

const user = {};

set(user, "profile.name", "John Doe");
set(user, ["profile", "age"], 30);

// user -> { profile: { name: "John Doe", age: 30 } }

⚡ Quick Reference

TaskCode patternResult
Nested dot path_.set(obj, "a.b", value)Creates a if missing
Array of keys_.set(obj, ["a", "b"], value)Same as dot path
Array index_.set(obj, "items[0].id", 1)Sets first array element
Update existing_.set(user, "profile.city", "NYC")Overwrites or adds key
Read back_.get(obj, "a.b")Use _.get()
Custom write rules_.setWith(obj, path, val, fn)See _.setWith()
Mutates?
Yes

In-place write

Creates path
Auto

Missing intermediates

Returns
object

Same reference

Pair with
_.get()

Read at path

🧰 Parameters

Arguments to _.set() and how Lodash applies them:

object Required

The target object. Lodash mutates this object directly and returns the same reference.

const state = {};
_.set(state, "ui.theme", "dark")
path Required

Location to write: string path, bracket notation, or array of keys. Same formats as _.get.

_.set(o, "profile.name")
_.set(o, ["profile", "name"])
value Required

The value assigned at the final segment. Replaces any existing value at that path.

_.set(user, "age", 31)
auto-create Behavior

Missing intermediate keys become plain objects. Numeric segments create or extend arrays.

_.set({}, "a.b.c", 1)
// { a: { b: { c: 1 } } }

If an intermediate value exists but is a primitive (string, number, boolean), Lodash may overwrite it to continue the path—verify structure before setting deep paths on existing data.

Examples Gallery

Practical _.set() patterns with sample output and interactive Try It Yourself labs.

📚 Getting Started

Build nested objects from scratch with dot paths and key arrays.

Example 1 — Create a nested profile

Start from an empty object and set profile.name and profile.age.

javascript
const user = {};

_.set(user, "profile.name", "John Doe");
_.set(user, ["profile", "age"], 30);

console.log(user);
// -> { profile: { name: "John Doe", age: 30 } }
Try It Yourself

How It Works

Lodash creates the profile object automatically because it did not exist yet.

Example 2 — Add to existing nested structure

Set a new sibling property without disturbing other nested keys.

javascript
const user = {
  profile: {
    address: { city: "New York" }
  }
};

_.set(user, "profile.name", "John Doe");

console.log(user);
// -> {
//      profile: {
//        address: { city: "New York" },
//        name: "John Doe"
//      }
//    }

📈 Practical Patterns

Deep paths, array indices, configuration objects, and read/write pairs.

Example 3 — Deep path auto-creation

Create multi-level nested objects in one call per leaf property.

javascript
const user = {};

_.set(user, "profile.name.first", "John");
_.set(user, "profile.name.last", "Doe");

console.log(user);
// -> { profile: { name: { first: "John", last: "Doe" } } }
Try It Yourself

Example 4 — Set values in arrays

Use numeric indices in the path to populate array elements.

javascript
const data = {};

_.set(data, "users[0].name", "Alice");
_.set(data, "users[1].name", "Bob");

console.log(data);
// -> { users: [{ name: "Alice" }, { name: "Bob" }] }
Try It Yourself

Example 5 — Application configuration

Build a nested config tree for theme and debug settings.

javascript
const config = {};

_.set(config, "app.theme.primaryColor", "#3366FF");
_.set(config, "app.debug", true);

console.log(config);
// -> { app: { theme: { primaryColor: "#3366FF" }, debug: true } }

🚀 Beyond the Basics

Combine with _.get() for data reshaping.

Example 6 — Read with _.get, write with _.set

Move nested data from one shape to another using the get/set pair.

javascript
const original = {};
_.set(original, "user.name", "Alice");
_.set(original, "user.age", 25);

const transformed = {};
_.set(transformed, "profile", _.get(original, "user"));

console.log(transformed);
// -> { profile: { name: "Alice", age: 25 } }

🧠 How _.set() Works

1

Parse path

Lodash normalizes the path string or key array into segments.

Input
2

Walk or create

For each segment except the last, ensure an object or array slot exists.

Build
3

Assign value

Set the final segment to value, replacing any previous value there.

Write
=

Object updated

The same object reference is returned, now containing the nested value.

📝 Notes

  • _.set() mutates the target object—clone first when immutability matters.
  • Missing intermediate keys are created automatically as plain objects (or array slots).
  • Setting a path overwrites the previous value at the final key.
  • Primitives along the path may be replaced if Lodash needs to continue deeper.
  • Use the same path formats as _.get() for consistency.
  • For custom intermediate objects (Maps, special merge rules), use _.setWith().

Conclusion

_.set() removes the tedium of building nested object trees by hand. Pass a path and value, and Lodash creates whatever structure is needed along the way. Pair it with _.get() for safe reads and remember that it mutates in place.

When you need control over how intermediate containers are created, continue to _.setWith(). To remove nested properties instead, see _.unset() in the Lodash object series.

💡 Best Practices

✅ Do

  • Know your object shape before setting deep paths
  • Use array key paths when segments contain dots
  • Clone before _.set() when immutability is required
  • Match path style with _.get() across your codebase
  • Return the object from _.set() for convenient chaining

❌ Don’t

  • Assume _.set() is non-mutating like _.pick()
  • Blindly set deep paths on API data you do not control
  • Overwrite primitives that should remain leaf values
  • Rely on sparse array behavior without testing edge indices
  • Forget that the final assignment replaces existing values

Key Takeaways

Knowledge Unlocked

Five things to remember about _.set()

Use these when writing nested data in JavaScript objects.

5
Core concepts
⚠️ 02

Mutates

In-place update.

Important
🚀 03

Auto-create

Builds missing path.

Power
🗃️ 04

Arrays

[0] indices.

Pattern
🔀 05

vs get

Write / read pair.

Related

❓ Frequently Asked Questions

_.set() writes a value at a nested path on an object. It mutates the object, creates missing intermediate objects or array slots along the path, and returns the same object reference.
Yes. _.set() always modifies the object you pass in. To avoid mutation, clone first: _.set(_.cloneDeep(obj), path, value) or _.set({}, path, value) when building fresh data.
A dot-path string like profile.name, bracket notation like users[0].name, or an array of keys like ["profile", "age"]. All forms reach the same nested location.
Lodash creates plain objects (or array slots for numeric indices) along the path automatically. You do not need to initialize empty nested objects manually.
_.get() reads at a path; _.set() writes at a path. They use the same path syntax but opposite directions—result is the read+invoke variant of get.
If an intermediate segment exists but is not an object (for example a string or number), _.set() may replace it to continue building the path. Plan paths carefully on existing data.
Did you know?

_.set returns the object you passed in, so you can chain writes: _.set(_.set({}, "a", 1), "b", 2). For immutable updates in UI state libraries, clone first with _.cloneDeep or build on a fresh object.

Practice _.set() in the Live Editor

Build nested objects, set array indices, and see results instantly.

Open Try It editor →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful