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

underpouch

v1.1.0

Published

An underscore API for PouchDB with added bonuses

Readme

underpouch logo

An underscore API for PouchDB with added bonuses!

npm install underpouch

usage

var PouchDB = require('pouchdb')
var _pouch = require('underpouch')

var db = new PouchDB('db')

Now you can query PouchDB with familiar _.underscore functions:

_pouch.findWhere(db, { author: "Shakespeare", year: 1611 }, (err, doc) => {
    //doc = { _id: 'example', _rev: 'xxx...', title: "Cymbeline", author: "Shakespeare", year: 1611 }
})

(note that the following examples return docs with _id and _rev but are trimmed, unless otherwise indicated, for brevity)

Collections (for sifting, sorting docs)


find
_pouch.find(db, truthTest, callback)
Looks through each doc in the db, returning the first one that passes a truth test.

  _pouch.find(db, (doc) => doc.magicNumber % 2 == 0, (err, doc) => {
    //doc = { name: 'magicDoc', magicNumber: 2 }
  })

filter
_pouch.filter(db, truthTest, callback)
Looks through each doc in the db, returning an array of docs that pass a truth test.

  _pouch.filter(db, (doc) => doc.number % 2 == 0, (err, docs) => {
    //docs = [{ number: 2 }, { number: 4 }, { number: 6 }}
  })

where
_pouch.where(db, properties, callback)
Looks through each doc in the db, returning an array of all the docs that contain all of the key-value pairs listed in properties.

  _pouch.where(playsDb, { author: "Shakespeare", year: 1611 }, (err, docs) => {
    /*docs = [{ title: "Cymbeline", author: "Shakespeare", year: 1611 },
    { title: "The Tempest", author: "Shakespeare", year: 1611 }] */
  })

findWhere
_pouch.findWhere(db, properties, callback)
Looks through the list and returns the first value that matches all of the key-value pairs listed in properties.

  _pouch.findWhere(db, {newsroom: "The New York Times"}, (err, doc) => {
    //doc = { year: 1918, newsroom: "The New York Times", reason: "For its public service in publishing in full so many official reports, documents and speeches by European statesmen relating to the progress and conduct of the war."}  
  })

max
Returns the doc with the maximum value. If no iteratee function is provided, defaults to _.id (parseInt will be used).

  _pouch.max(db, (stoogeDoc) => stoogeDoc.age, (err, doc) => {
    //doc = { name: 'curly', age: 60 }
  })

all !
_pouch.all(db, callback)
Returns an array of all the docs in the db

  _pouch.all(db, (err, allDocs) => {
    //allDocs = [{_id: 'all'},{_id: 'the'}, {_id: 'docs'}]
  })

deleteNow !
_pouch.deleteDocs(db, docOrDocId, callback)
Deletes a given document without requiring revision or giving up on conflict (adds { _deleted : true })

  let doc = { _id : 'any' , _rev : 'thing' }
  _pouch.deleteNow(db, doc, (err) => {
    //err if doc not found
  })

deleteDocs !
_pouch.deleteDocs(db, callback)
Deletes all docs in database, without deleting the database (adds { _deleted : true } to each doc)

  _pouch.deleteDocs(db, (err, res) => {
    //res is a list of the ids/revs of the deleted docs
  })

Object Functions (for modifying docs)


extend
_pouch.extend(db, destinationDocId, sourceDoc, callback)
Copy all of the properties in the source doc over to the destination doc, put and return the destination doc with its updated rev. It's in-order, so the last source will override properties of the same name in previous arguments.

  _pouch.extend(db, 'user', { email: [email protected] }, (err, updatedDoc) => {
    //updatedDoc = { email: "[email protected]", name: "Jeff", age: 35 }
  })

extendPut !
_pouch.extendPut(db, destinationDocId, sourceDoc, callback)
Like _pouch.extend but put()'s the sourceDoc even if destination doc is not existing.

  _pouch.extendPut(db, { 'some-id-that-doesnt-exist', {name: "Sara"}, (err, extendedDoc) => {
    //extendedDoc = { _id: "some-id-that-doesnt-exist", name: "Sara" }
  })

extendPutOrPost !
_pouch.extendPutOrPost(db, destinationDoc, sourceDoc, callback)
Like _pouch.extendPut but will post() the doc if no id is provided.

  _pouch.extendPut(db, {name: "Sara"}, (err, extendedDoc) => {
    //extendedDoc = { _id: "262db426-2b2a...", name: "Sara" }
  })

merge ! (lodash)
_pouch.merge(db, destinationDocId, sourceDoc, callback)
Like _pouch.extend but uses lodash's merge so that child properties are merged, not overwritten. Ie: _pouch.extend will overwrite properties whereas _pouch.merge will merge them.

  //originalDoc = { _.id: 'food', fruits: ['mango', 'lemon']}
  _pouch.merge(db, 'food', { fruits: ['lime, kiwi'] }, (err, updatedDoc) => {
    //updatedDoc = { _.id: 'food', fruits: ['mango', 'lemon', 'lime', 'kiwi']}
  })

mergePutOrPost !
_pouch.merge(db, destinationDocId, sourceDoc, callback)
Like _pouch.mergePutOrPost but will post (if no _id) or put the doc if not already existing.

  _pouch.mergePutOrPost(db, { fruits: ['lime, kiwi'] }, (err, updatedDoc) => {
    //updatedDoc = { _.id: "262db426-2b2a...", fruits: ['lime, kiwi']}
  })

replace ! _pouch.replace(db, doc, callback) Overwrites an existing doc, regardless of revision (shortcut for doing db.get and then db.put) or if doc existing or not (posts if not existing).

  //no doc existing: 
  _p.replace(db, { _id : 'favorite-food', value : 'pizza' }, (err, replacedDoc) => {
    //no rev necessary: 
    _p.replace(db, { _id : 'favorite-food', value : 'ice cream' }, (err, repacedDoc2) => {
      //replacedDoc2 = { _id : 'favorite-food', value : 'ice cream' } }
    })
  })