npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

nested-read-write

v1.0.1

Published

JavaScript module for doing operations on nested objects

Downloads

14

Readme

Nested Read Write

A powerful tool to select and update properties nested deep within an object.

Example

const nrw = require('nested-read-write')
const path = nrw.parse('users[].name')
path.read({
  users: [
    {name: "Alex", age: 25},
    {name: "Sam", age: 30}
  ]
})
// returns ["Alex", "Sam"]

path.write({}, ["Alice", "Bob"])
// returns {users: [{name: "Alice"}, {name: "Bob"}]}

Interface

nrw.parse(path)

Creates a Path object from path string.

Path.prototype.read(src)

Returns value from src according to Path object.

Path.prototype.write(dest, value)

Mutates dest with value according to Path object, and returns mutated dest.

Path.prototype.standardize()

Cleans up the Path object by removing redundant operations. (E.g. "&.a" would standardize to "a")

Path.prototype.toString()

Rebuilds the path string. It should be nearly identical, but with whitespace removed.

Quick Guide

| Operation | Read Description | Write Description | | - | - | - | | & | Gets relative source | invalid | | .name | Gets name property | Sets name property | | [name] | Gets name property | Sets name property | | [path] | Gets value at path | Sets value at path | | [ ] | Gets shallow array copy | Sets elements of relative source to elements of value | | | arrayop | Gets flattened array | invalid | | [begin:end:step] | Gets slice | invalid | | [n1, n2, n3] | Gets array at indices ni | Sets indices ni to value[i] | | [path1, path2, path3] | Gets array of pathi values | Writes value[i] to pathi | | [@] | invalid | Concatenates values to array | | [@n] | invalid | Inserts values into array before index n | | { } | Gets shallow object copy | Assigns entries of value to relative source | | { path1, path2, path3 } | Gets object containing only pathi values | Writes pathi value to pathi | | { src1: dest1, src2: dest2 } | Gets new object with value at path srci relocated to desti | Writes srci value to desti |

Chaining

Chaining operations can be a bit confusing. One way to understand it is through seeing how operations distribute.

| Chain | Distributed Chain | | - | - | | [a.b].c | [a.b.c] | | a[b.c] | [a.b.c] | | [a, b].c | [a.c, b.c] | | a[b, c] | [a[c], a[b]] | | {a: b}.c | {a.c: b} | | a{b: c} | {a.b: c} |

Reading .read(source)

An empty string will simply return the original source argument.

Reference

& returns the relative source. For example, "x[&]" will return source.x.

Property

Both .x and [x] can be used to get source.x. They can be chained together via concatenation.

. should only be used for valid variable names.

[ ] can be used for all cases, such at array indices, variable names, quoted strings, and even nested paths.

The following will all get source.a.b.c

a.b.c
[a].b.c
a[b].c
a[b.c]

Array

Array operations will collect values into an array. Shallow operations on this array will have no effect on the source object. You can combine

Consider a case where source = [[1,2],[3,4]]

nrw.parse("").read(source).push(5)        // mutates source
nrw.parse("[]").read(source).push(5)      // doesn't mutate source
nrw.parse("[]").read(source)[0].push(5)   // mutates source
nrw.parse("[][]").read(source)[0].push(5) // doesn't mutate source

| can be used before any array operation to tell it to flatten

nrw.parse("|[]").read(source)  // returns [1,2,3,4]

[begin:end:step] creates a slice using logic similar to the Python slice operation.

[1,5,2] will return [source[1], source[5], source[2]]. A trailing comma is needed to force a single element sequence. For example [0] gets source[0] while [0,] creates [source[0]].

[a.b,x.y] will return [source.a.b, source.x.y]. This also will require tailing comma to force a sequence. If you want to mix array accesses it can be done like so [[0], length] to get [source[0], source.length].

Object

Object operations will collect values into an object. Shallow operations on this object will have no effect on the source object. Mutations should function similar to arrays.

{src: dest} will take do src.read() on the relative source and then dest.write() the result to the current result.

{path} is shorthand for {path: path}.

nrw.parse('{a,b:c}').read({a:1,b:2}) // returns {a:1,c:2}

Writing .write(dest, value)

Write operations function as you might expect once you understand read operations. There are a few caveats specific to write operations, though.

Property

When you write to property that doesn't exist, objects/arrays will be created to ensure you write are setting the property of something other than undefined.

Array

Array operations expect that the value being fed into them is an array.

[] will copy value elements into the array. If the relative destination is large, it will

[@] appends value elements to the end of the array.

[@0] will insert value elements before 0. A negative index relative to the array length can also be given. [@-1] inserts before the last element

Object

{} will do Object.assign() of value into the relative destination.

{src: dest} reads the src path from value and writes it to the dest path of the relative destination.

License

MIT (See LICENSE.md)