Offline-First Web Application Using Redux and PouchDB

How to build an offline-first web application in five steps.

What is an Offline-First Web Application?

Basically, Offline-First Web Applications are web apps that can run without an internet connection. In Offline-First applications, local storage data is used as the main data source, and the data is continuously synchronized with a remote database. If an interruption occurs, the synchronization and database reboot itself once the connectivity is back.

Why Use Offline-First Web Application Pattern?

JotForm 4.0 allows users to continue editing forms offline.

If you design your web application as an offline-first web application, you gain more than just offline functionality:

Your pages will load and behave more efficiently

Your users can still work productively with poor internet connections

You can prevent occasional data-losses because the data is stored on both local and remote databases

At JotForm, we have been working on an amazing new version of our product for the last 1.5 years. We have achieved offline-first and collaboration thanks to React / Redux and PouchDB. This is the story of how we did it.

Using React, Redux and PouchDB

React and Redux Architecture

We are using a single store React architecture in developing JotForm 4.0. If you don’t know about React and Redux, see this post Why you should use React before going any further.

2. PouchDB

According to its creators, “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.”

PouchDB is a client-side no-SQL database. And we use it to store our local data. You can read more about PouchDB here.

Here is an interesting story about how we found out about PouchDB. During our third Hack Week last year (one of the weeklong hackathons we hold at JotForm), one of our goals was to build a Collaborative Form Builder. Most teams accomplished this using socket.io. Unfortunately, they all sucked. They kept crashing even when there were only two people editing the form. Except one: Our friends on the JotForm Growth Team had created an amazing form builder that kept working even when we had 30 people editing the same form at same time. When we asked their secret, they said they used PouchDB. That was the first time we had heard of PouchDB. And boy, did it make a big impression on us!

3. How to use Redux and PouchDB

If you are using Redux as store, you can simply integrate PouchDB to your reducers. There is a good open source package called by redux-pouchdb.

After installing the library using npm, you need to create a pouch database in your configure_store.js file and you need to save your database to your createStore function.

After these steps, you just need to export your reducers as a “persistentReducer” as shown above for synchronizing your reducer to PouchDB. And now, all of your reducer changes will be in your local pouch.

4. Synchronizing Your Local Data with a Remote Database

a) Using CouchDB

When you use CouchDB as remote database, it is very easy to synchronize your local changes with a remote database. PouchDB offers you a sync method, which enables one or two ways to synchronize data. You simply need to use Pouch.sync method in the beginning. After that, Pouch will synchronize data whenever it can. You don’t even need to check for internet connection. It does the hard work for you. But it isn’t perfect. Conflict management can still be painful.

b) Using Your Existing Database

As we did with JotForm 4.0, you may want to use PouchDB to just store local data. You need to send your local changes to your database manually, and you will also need to understand each user’s network state on the way.

JotForm checks network calls with some safeguards in online mode. If a user loses network connection, we switch to offline mode. Users can continue to work without any network saves. However, in the background, we keep trying to access our servers. If connection comes back, we start sending offline data to our API.

But what if the user closes window?

All changes are saved in the reducer and it is synchronized with PouchDB. So, after making some changes, if the user closes the browser while still offline, no data will be lost. Our data is safely saved in our pouch.

JotForm 4.0 Offline Sample

5. Service Workers

Up to this point, we have allowed the user to work with lost network connection. What if the user wants to use our application after closing their computer?

Can we still make our application accessible without connection?

Service workers are scripts that run in the background within the browser. It allows you to cache files, push notifications, send custom responses, etc.

If the browser supports service workers, we can use them to cache and store our files on the client side. Here is a service workers supported browsers list.

Service Worker Lifecycle (Credits: Mozilla Foundation)

Service workers have a lifecycle. When they are installed for the first time, they run “installed” event triggers. And every time they get activated, an “activated” event is triggered. With these events, we can add our files to the service worker cache on install. After that, we can access them through service workers.

So, if we cache a file using a service worker, no network-call will need to be made to our servers. You can look-up Google’s sample for a cool example.

Once cached, you can see in your browser network tab that your files start coming from the service worker.

But keep in mind that service workers do not work in incognito mode.

In JotForm 4.0, we’ve used the latest technologies to provide the best user experiences. Our Offline Mode is one of our new features that makes us incredibly proud. We are releasing JotForm’s new form builder on February 1, so stay tuned!

Make your web applications offline-first. Your users will appreciate it.