Library / SDK
apache/couchdb-nano avatar
apache/couchdb-nano

Nano is the CouchDB client that refuses to abstract much

Nano: The official Apache CouchDB library for Node.js

691 stars167 forksJavaScriptApache-2.0

At a glance

What is it?
Nano is the official Apache CouchDB client for Node.js, and its design goal is stated as minimalism, with only a minimum of abstraction between you and CouchDB. It has no runtime dependencies at all, ships its own TypeScript definitions, and version 11 dropped the old HTTP layer in favour of Node's built-in fetch, which is why Node 16 users are still on Nano 10.
Who is it for?
Adopt Nano if you are building a Node.js service on CouchDB and want the client's surface to match the HTTP API rather than hide it, since the error semantics and the endpoint names are the ones you already know from CouchDB. Skip it if you need a client with its own object mapping or retry policy, because there is no abstraction layer to configure, and if you are on Node 16 or older, where version 11 does not work and Nano 10 is the last option.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 63 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The whole design goal is that you already know CouchDB

Nano is the official Apache CouchDB library for Node.js, and the feature list starts with the constraint that defines it.

Minimalistic, with only a minimum of abstraction between you and CouchDB. Pipes, proxying requests from CouchDB directly to your end user, though only with the AsStream functions. Promises, with the vast majority of library calls returning native Promises. TypeScript, with detailed TypeScript definitions built in. And errors, proxied directly from CouchDB, with the argument that if you know CouchDB you already know nano.

That last one is the design statement and it is worth taking seriously. Most database clients hide the wire format behind a mapper and a repository abstraction, which is comfortable until you need a CouchDB feature the client does not model. Nano does not have that gap, because a method is a CouchDB endpoint with the same name and the same parameters, and an error is the CouchDB error with the same shape.

The consequence for a reader is that nano is easy to learn if you know the HTTP API, and gives you nothing extra if you do not.

The project is JavaScript, Apache-2.0 licensed, published to npm as nano, with the last push on 2026-08-21 and releases v11.0.7, v11.0.6 and v11.0.5 through 2026.

Version 11 dropped its own HTTP client for Node's fetch

The note at the top of the documentation is the most consequential thing in it, and it is a breaking change rather than a deprecation.

Nano 11 and above is a breaking change for Node.js versions 16 and older. Nano 11 uses Node.js's built-in fetch HTTP client, and that is only available in Node.js versions 18 or later. If you are using Node 16 or older then continue using Nano 10, and there is a migration guide for moving from Nano 10 to Nano 11 in the repository.

The package manifest is consistent with the note and slightly stricter than the prose. The engines field requires Node 20.0 or newer, and the dependency list is empty, with the dependencies object present but containing nothing.

That empty dependency list is the other thing worth noticing. A CouchDB client with no runtime dependencies means no request library, no promise library, no uuid library, nothing. The HTTP work is done by the platform, and the only devDependencies are the TypeScript compiler, the Node types and undici. The build script is a single line, `tsc lib/nano.d.ts && node --test./test/*.test.js`, so the type definitions are compiled and then the test suite runs on the Node built-in test runner.

The type definitions are a first-class output rather than an afterthought. The types field points at./lib/nano.d.ts, the main field at./lib/nano.js, and the pre-commit hook runs the test script, so the definitions cannot drift from the implementation without a commit failing.

Connecting is one call, and the database handle is a separate object

The getting started section is short enough to be the whole quick start.

js
const nano = require('nano')('http://127.0.0.1:5984');

That is the connection. Creating a database is a call on the connection:

js
nano.db.create('alice');

And working with an existing database gives you a scoped handle:

js
const alice = nano.db.use('alice');

That handle is the object you keep, and it is what the rest of the API hangs off. The database functions on it are `db.insert`, `db.get`, `db.destroy`, `db.head`, `db.bulk`, `db.list`, `db.fetch`, `db.fetchRevs` and `db.createIndex`, and the partitioned variants take a partition key first.

The deprecation note is on the connection line, and it is worth acting on. Supplying authentication credentials in the URL, for example `http://admin:mypassword@localhost:5984`, is deprecated, and you should use `nano.auth` instead.

That is not only about tidiness. A credential in a URL ends up in log files, in error messages and in process listings, and the URL form also leaks into anything that echoes the request. The replacement is a property on the client rather than part of an address you copy around.

The document functions have the same shape as the HTTP API underneath, which is the point. A `db.get` is a GET on the document, a `db.insert` is a PUT or POST on it, and `db.head` is the HEAD request that tells you whether a document exists without fetching it.

Everything is a promise or a stream, and the streams proxy

The asynchronous model has two forms, and the documentation states them plainly.

Calls like `nano.db.create` are making HTTP API calls to the CouchDB service, and such operations are asynchronous. There are two ways to receive the data back. As promises:

js
nano.db.create('alice').then((data) => {
  // success - response is in 'data'
}).catch((err) => {
  // failure - error information is in 'err'
})

Or in the async/await style, which the documentation shows next.

Many database functions have an AsStream variant, and those are the ones with the pipes feature. The streams are what let a CouchDB response reach your HTTP response without buffering the whole thing in memory, which for a large document list or a change feed is the difference between a working proxy and an out-of-memory process.

The API surface in the table of contents shows how much of CouchDB is covered. The database functions include create, get, destroy, list, compact, replicate, the replication enable, query and disable calls, changes and changesAsStream, info, use, request, config and updates.

The document functions cover insert, destroy, get, head, bulk, list, fetch, fetchRevs, createIndex and a changesReader. There are partitioned variants for every read operation, partitionedList, partitionedFind, partitionedSearch, partitionedView and their streaming forms, partitionedFindAsStream, partitionedSearchAsStream and partitionedViewAsStream, and there is partitionedInfo for the partition metadata.

Then the multipart functions for the two-step upload, and the attachment functions for insert, get and destroy, each with a streaming variant where it makes sense.

The parts that are CouchDB rather than nano

A few things in the API are not really client-side features, and recognising them saves confusion.

The views and design functions operate on design documents. There is db.view and db.viewAsStream, db.viewWithList and db.viewWithListAsStream, db.show, db.atomic, db.search and db.searchAsStream, and db.find and db.findAsStream for Mango selectors.

Cookie authentication is a documented section of its own, and it is worth knowing about because it is how you authenticate as a user against a CouchDB database rather than as an admin, and it works through a login call that returns a cookie to send with subsequent requests.

The advanced features section covers the things that are not obvious from the endpoint names. Getting uuids is a CouchDB endpoint you call to get identifiers for new documents, which is how you create a document with an id you chose rather than one the server assigned. Extending nano is how you add your own methods to the client object. And pipes is the streaming feature described above, where the pipe function proxies requests from CouchDB directly to your end user, limited to the AsStream functions.

The db.request function is the escape hatch, and it is the most useful thing to know about. It takes an options object and makes an arbitrary request to the CouchDB HTTP API, so anything the server supports is reachable even if the client has no wrapper for it. For a client whose stated goal is minimal abstraction, having a documented raw request method is the completion of the design.

There is also nano.config for the configuration endpoints and nano.updates, which is the CouchDB update notification call, and the replication functions take an id that you query later with nano.db.replication.query.

Editorial conclusion

Adopt Nano if you are building a Node.js service on CouchDB and want the client's surface to match the HTTP API rather than hide it, since the error semantics and the endpoint names are the ones you already know from CouchDB. Skip it if you need a client with its own object mapping or retry policy, because there is no abstraction layer to configure, and if you are on Node 16 or older, where version 11 does not work and Nano 10 is the last option. Verify first that your Node version is 20 or newer, that you have moved off credentials embedded in the URL since that form is deprecated in favour of nano.auth, and whether you need the streaming variants, since pipes are only available on the AsStream functions.

Frequently asked questions

How do I install and connect Nano to CouchDB?

Install npm and then run `npm install nano`, or save it as a project dependency with `npm install --save nano`. Connect with `const nano = require('nano')('http://127.0.0.1:5984')`, then create a database with `nano.db.create('alice')` or get a handle on an existing one with `nano.db.use('alice')`.

What changed in Nano 11?

Nano 11 uses Node.js's built-in fetch HTTP client instead of its own, which makes it a breaking change for Node.js 16 and older, since built-in fetch is only available from Node 18. The package manifest requires Node 20 or newer, and a migration guide for moving from Nano 10 to Nano 11 is in the repository.

How do I authenticate with Nano without putting credentials in the URL?

Supplying authentication credentials in the URL is deprecated, and the documented replacement is nano.auth. The client also has a separate cookie authentication section, and db.request gives you a raw pass to the CouchDB HTTP API for anything the client does not wrap.

Official sources

  1. apache/couchdb-nano on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/apache-couchdb-nano.svg)](https://hysenlabs.com/projects/apache-couchdb-nano)

Was this useful?