PouchDB Tutorial: Building an Offline App with PouchDB and CouchDB

PouchDB was created to help web developers build applications that work as well offline as they do online.

PouchDB is an open-source JavaScript database inspired by Apache CouchDB that is designed to run well within the browser.

PouchDB was created to help web developers build applications that work as well offline as they do online.

It enables applications to store data locally while offline, then synchronize it with CouchDB and compatible servers when the application is back online, keeping the user’s data in sync no matter where they next login.

We will start with a template of the project where all the data related functions have been replaced with empty stubs. Download and unzip pouchdb-getting-started-todo.zip. When dealing with XHR and IndexedDB you are better off running web pages from a server as opposed to a filesystem. To do this you can run:

The first thing we shall do is start writing items to the database. The main input will call addTodo with the current text when the user presses Enter. We can complete this function with the following code:

In PouchDB each document is required to have a unique _id. Any subsequent writes to a document with the same _id will be considered updates. Here we are using a date string as an _id. For our use case, it will be unique, and it can also be used to sort items in the database. You can use db.post() if you want random ids. The _id is the only thing required when creating a new document. The rest of the object you can create as you like.

The callback function will be called once the document has been written (or failed to write). If the err argument is not null, then it will have an object explaining the error, otherwise the result will hold the result.

We have included a helper function redrawTodosUI that takes an array of todos to display, so all we need to do is read the todos from the database. Here we will simply read all the documents using db.allDocs. The include_docs option tells PouchDB to give us the data within each document, and the descending option tells PouchDB how to order the results based on their _id field, giving us newest first.

We dont want to refresh the page to see new items. More typically you would update the UI manually when you write data to it, however, in PouchDB you may be syncing data remotely, so you want to make sure you update whenever the remote data changes. To do this we will call db.changes which subscribes to updates to the database, wherever they come from. You can enter this code between the remoteCouch and addTodo declaration:

var remoteCouch = false;
db.changes({
since: 'now',
live: true
}).on('change', showTodos);
// We have to create a new todo document and enter it in the database
function addTodo(text) {

So every time an update happens to the database, we redraw the UI to show the new data. The live flag means this function will continue to run indefinitely. Now try entering a new todo and it should appear immediately.

This is similiar to creating a document, however the document must also contain a _rev field (in addition to _id), otherwise the write will be rejected. This ensures that you dont accidently overwrite changes to a document.

You can test that this works by checking a todo item and refreshing the page. It should stay checked.

Similiar to editing a document, both the _id and _rev properties are required. You may notice that we are passing around the full object that we previously read from the database. You can of course manually construct the object, like: {_id: todo._id, _rev: todo._rev}, but passing around the existing object is usually more convenient and less error prone.

To replicate directly with CouchDB, you need to make sure CORS is enabled. Only set the username and password if you have set them previously. By default, CouchDB will be installed in “Admin Party,” where username and password are not needed. You will need to replace myname.example.com with your own host (127.0.0.1:5984 if installed locally):

You can enable CORS in CouchDB using curl or the Futon web interface, but we’ve saved you some time by making a Node script called add-cors-to-couchdb. Just run:

Now we will have the todo list sync. Back in app.js we need to specify the address of the remote database. Remember to replace user, pass and myname.example.com with the credentials of your own CouchDB instance:

db.replicate() tells PouchDB to transfer all the documents to or from the remoteCouch. This can either be a string identifier or a PouchDB object. We call this twice: once to receive remote updates, and once to push local changes. Again, the live flag is used to tell PouchDB to carry on doing this indefinitely. The callback will be called whenever this finishes. For live replication, this will mean an error has occured, like losing your connection or you canceled the replication.

You should be able to open the todo app in another browser and see that the two lists stay in sync with any changes you make to them. You may also want to look at your CouchDB’s Futon administration page and see the populated database.

You’ve completed your first PouchDB application. This is a basic example, and a real world application will need to integrate more error checking, user signup, etc. But you should now understand the basics you need to start working on your own PouchDB project. If you have any more questions…