# dset

> A tiny (194B) utility for safely writing deep Object values~!

Latest version **3.1.4** (published 2024-09-09) · MIT license · 0 weekly downloads

## Install

```sh
npm install dset
pnpm add dset
yarn add dset
bun add dset
```

## Health

**Score 40/100 (D)** — status: maintenance-mode.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

Negative: stale; low maintenance score.

## Facts

| | |
|---|---|
| Version | 3.1.4 |
| Published | 2024-09-09 |
| First published | 2018-02-21 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=4 |
| Dependencies | 0 |
| Unpacked size | 10.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 782 |
| Author | Luke Edwards |
| Maintainers | lukeed |
| Keywords | deepset, values, object, write, deep, safe, set |

## Links

- npm: https://www.npmjs.com/package/dset
- Repository: https://github.com/lukeed/dset
- Homepage: https://github.com/lukeed/dset#readme
- Issues: https://github.com/lukeed/dset/issues
- npm.io page: https://npm.io/package/dset

## Alternatives

- [jsforce](https://npm.io/package/jsforce.md) — 851.2K weekly downloads
- [react-native-qrcode-svg](https://npm.io/package/react-native-qrcode-svg.md) — 693.5K weekly downloads
- [@salesforce/plugin-data](https://npm.io/package/@salesforce/plugin-data.md) — 394.9K weekly downloads
- [@backstage/plugin-search-common](https://npm.io/package/@backstage/plugin-search-common.md) — 308.5K weekly downloads
- [@chain-registry/types](https://npm.io/package/@chain-registry/types.md) — 38.4K weekly downloads

## Recent versions

- 3.1.4 (latest) — 2024-09-09
- 3.1.3 — 2023-10-25
- 3.1.2 — 2022-05-03
- 3.1.1 — 2021-10-27
- 3.1.0 — 2021-02-24
- 3.0.0 — 2021-01-28
- 2.1.0 — 2021-01-27
- 2.0.1 — 2018-09-08
- 2.0.0 — 2018-09-07
- 1.0.1 — 2018-02-21
- 1.0.0 — 2018-02-21
- 0.0.0 — 2018-02-21

## README

# dset [![CI](https://github.com/lukeed/dset/workflows/CI/badge.svg?branch=master&event=push)](https://github.com/lukeed/dset/actions) [![codecov](https://badgen.net/codecov/c/github/lukeed/dset)](https://codecov.io/gh/lukeed/dset)

> A tiny (197B) utility for safely writing deep Object values~!

For _accessing_ deep object properties, please see [`dlv`](https://github.com/developit/dlv).

> **Using GraphQL?** You may want `dset/merge` – see [Merging](#merging) for more info.

## Install

```sh
$ npm install --save dset
```

## Modes

There are two "versions" of `dset` available:

#### `dset`
> **Size (gzip):** 197 bytes<br>
> **Availability:** [CommonJS](https://unpkg.com/dset/dist/index.js), [ES Module](https://unpkg.com/dset/dist/index.mjs), [UMD](https://unpkg.com/dset/dist/index.min.js)

```js
import { dset } from 'dset';
```

#### `dset/merge`
> **Size (gzip):** 307 bytes<br>
> **Availability:** [CommonJS](https://unpkg.com/dset/merge/index.js), [ES Module](https://unpkg.com/dset/merge/index.mjs), [UMD](https://unpkg.com/dset/merge/index.min.js)

```js
import { dset } from 'dset/merge';
```


## Usage

```js
import { dset } from 'dset';

let foo = { abc: 123 };
dset(foo, 'foo.bar', 'hello');
// or: dset(foo, ['foo', 'bar'], 'hello');
console.log(foo);
//=> {
//=>   abc: 123,
//=>   foo: { bar: 'hello' },
//=> }

dset(foo, 'abc.hello', 'world');
// or: dset(foo, ['abc', 'hello'], 'world');
console.log(foo);
//=> {
//=>   abc: { hello: 'world' },
//=>   foo: { bar: 'hello' },
//=> }

let bar = { a: { x: 7 }, b:[1, 2, 3] };
dset(bar, 'b.1', 999);
// or: dset(bar, ['b', 1], 999);
// or: dset(bar, ['b', '1'], 999);
console.log(bar);
//=> {
//=>   a: { x: 7 },
//=>   b: [1, 999, 3],
//=> }

dset(bar, 'a.y.0', 8);
// or: dset(bar, ['a', 'y', 0], 8);
// or: dset(bar, ['a', 'y', '0'], 8);
console.log(bar);
//=> {
//=>   a: {
//=>     x: 7,
//=>     y: [8],
//=>   },
//=>   b: [1, 999, 3],
//=> }

let baz = {};
dset(baz, 'a.0.b.0', 1);
dset(baz, 'a.0.b.1', 2);
console.log(baz);
//=> {
//=>   a: [{ b: [1, 2] }]
//=> }
```

## Merging

The main/default `dset` module forcibly writes values at the assigned key-path. However, in some cases, you may prefer to _merge_ values at the key-path. For example, when using [GraphQL's `@stream` and `@defer` directives](https://foundation.graphql.org/news/2020/12/08/improving-latency-with-defer-and-stream-directives/), you will need to merge the response chunks into a single object/list. This is why `dset/merge` exists~!

Below is a quick illustration of the difference between `dset` and `dset/merge`:

```js
let input = {
  hello: {
    abc: 123
  }
};

dset(input, 'hello', { world: 123 });
console.log(input);

// via `dset`
//=> {
//=>   hello: {
//=>     world: 123
//=>   }
//=> }

// via `dset/merge`
//=> {
//=>   hello: {
//=>     abc: 123,
//=>     world: 123
//=>   }
//=> }
```


## Immutability

As shown in the examples above, all `dset` interactions mutate the source object.

If you need immutable writes, please visit [`clean-set`](https://github.com/fwilkerson/clean-set) (182B).<br>
Alternatively, you may pair `dset` with [`klona`](https://github.com/lukeed/klona), a 366B utility to clone your source(s). Here's an example pairing:

```js
import { dset } from 'dset';
import { klona } from 'klona';

export function deepset(obj, path, val) {
  let copy = klona(obj);
  dset(copy, path, val);
  return copy;
}
```


## API

### dset(obj, path, val)

Returns: `void`

#### obj

Type: `Object`

The Object to traverse & mutate with a value.

#### path

Type: `String` or `Array`

The key path that should receive the value. May be in `x.y.z` or `['x', 'y', 'z']` formats.

> **Note:** Please be aware that only the _last_ key actually receives the value!

> **Important:** New Objects are created at each segment if there is not an existing structure.<br>However, when integers are encounted, Arrays are created instead!

#### value

Type: `Any`

The value that you want to set. Can be of any type!


## Benchmarks

For benchmarks and full results, check out the [`bench`](/bench) directory!

```
# Node 10.13.0

Validation:
  ✔ set-value
  ✔ lodash/set
  ✔ dset

Benchmark:
  set-value    x 1,701,821 ops/sec ±1.81% (93 runs sampled)
  lodash/set   x   975,530 ops/sec ±0.96% (91 runs sampled)
  dset         x 1,797,922 ops/sec ±0.32% (94 runs sampled)
```


## Related

- [dlv](https://github.com/developit/dlv) - safely read from deep properties in 120 bytes
- [dequal](https://github.com/lukeed/dequal) - safely check for deep equality in 247 bytes
- [klona](https://github.com/lukeed/klona) - quickly "deep clone" data in 200 to 330 bytes
- [clean-set](https://github.com/fwilkerson/clean-set) - fast, immutable version of `dset` in 182 bytes


## License

MIT © [Luke Edwards](https://lukeed.com)

---
_Source: https://npm.io/package/dset · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
