DEV Community

Nadim Chowdhury
Nadim Chowdhury

Posted on

Building a Progressive Web App (PWA) with the MERN Stack

Progressive Web Apps (PWAs) are modern web applications that offer a native app-like experience, including offline capabilities, push notifications, and improved performance. In this blog post, we'll explore how to build a PWA using the MERN (MongoDB, Express, React, Node.js) stack.

Why Build a PWA?

  • Offline Functionality: PWAs can work without an internet connection.
  • Performance Boost: Faster load times with caching and service workers.
  • Push Notifications: Engage users with timely updates.
  • No App Store Hassle: Users can install PWAs directly from the browser.

Setting Up the MERN Stack

Before making our app a PWA, let’s set up a MERN stack application:

Backend (Node.js & Express)

  1. Initialize a Node.js project:
   mkdir mern-pwa && cd mern-pwa
   npm init -y
Enter fullscreen mode Exit fullscreen mode
  1. Install dependencies:
   npm install express mongoose cors dotenv
Enter fullscreen mode Exit fullscreen mode
  1. Create a simple Express server:
   const express = require('express');
   const mongoose = require('mongoose');
   require('dotenv').config();

   const app = express();
   app.use(express.json());

   mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true })
      .then(() => console.log('MongoDB connected'))
      .catch(err => console.error(err));

   app.get('/', (req, res) => res.send('API Running'));

   app.listen(5000, () => console.log('Server running on port 5000'));
Enter fullscreen mode Exit fullscreen mode

Frontend (React)

  1. Create a React app:
   npx create-react-app client
   cd client
   npm install axios
Enter fullscreen mode Exit fullscreen mode
  1. Connect the React app to the backend by adding a proxy in package.json:
   "proxy": "http://localhost:5000"
Enter fullscreen mode Exit fullscreen mode
  1. Fetch data from the backend in App.js:
   import { useEffect, useState } from 'react';
   import axios from 'axios';

   function App() {
       const [message, setMessage] = useState('');

       useEffect(() => {
           axios.get('/')
               .then(res => setMessage(res.data))
               .catch(err => console.error(err));
       }, []);

       return <h1>{message}</h1>;
   }

   export default App;
Enter fullscreen mode Exit fullscreen mode

Making the App a PWA

1. Register a Service Worker

Service workers enable offline functionality. Modify index.js:

   if ('serviceWorker' in navigator) {
       window.addEventListener('load', () => {
           navigator.serviceWorker.register('/service-worker.js')
               .then(reg => console.log('Service Worker registered:', reg))
               .catch(err => console.error('Service Worker registration failed:', err));
       });
   }
Enter fullscreen mode Exit fullscreen mode

2. Create a Service Worker

Inside public/, create service-worker.js:

   const CACHE_NAME = 'pwa-cache-v1';
   const urlsToCache = [
       '/',
       '/index.html',
       '/static/js/bundle.js'
   ];

   self.addEventListener('install', event => {
       event.waitUntil(
           caches.open(CACHE_NAME)
               .then(cache => cache.addAll(urlsToCache))
       );
   });

   self.addEventListener('fetch', event => {
       event.respondWith(
           caches.match(event.request)
               .then(response => response || fetch(event.request))
       );
   });
Enter fullscreen mode Exit fullscreen mode

3. Add a Web Manifest

Create public/manifest.json:

   {
       "short_name": "MERN PWA",
       "name": "MERN Stack PWA",
       "icons": [
           {
               "src": "icon.png",
               "type": "image/png",
               "sizes": "192x192"
           }
       ],
       "start_url": "/",
       "display": "standalone",
       "background_color": "#ffffff",
       "theme_color": "#000000"
   }
Enter fullscreen mode Exit fullscreen mode

Reference the manifest in public/index.html:

   <link rel="manifest" href="/manifest.json">
Enter fullscreen mode Exit fullscreen mode

4. Enable HTTPS (Optional for Local Development)

PWAs require HTTPS for service workers to function properly. For local testing, use:

   npm install -g serve
   serve -s build
Enter fullscreen mode Exit fullscreen mode

Deploying the PWA

  1. Backend: Deploy the Node.js server on a platform like Heroku or Render.
  2. Frontend: Deploy the React app on Vercel, Netlify, or Firebase Hosting.
  3. Ensure the start_url in manifest.json matches the deployed domain.

Conclusion

Building a PWA with the MERN stack enhances user experience by making web apps faster, installable, and accessible offline. By integrating service workers and a web manifest, your app can behave more like a native mobile application while still leveraging the power of web technologies.

Are you building a PWA? Let us know your experience in the comments below!

Support My Work ❤️

If you enjoy my content and find it valuable, consider supporting me by buying me a coffee. Your support helps me continue creating and sharing useful resources. Thank you!

Connect with Me 🌍

Let’s stay connected! You can follow me or reach out on these platforms:

🔹 YouTube – Tutorials, insights & tech content

🔹 LinkedIn – Professional updates & networking

🔹 GitHub – My open-source projects & contributions

🔹 Instagram – Behind-the-scenes & personal updates

🔹 X (formerly Twitter) – Quick thoughts & tech discussions

I’d love to hear from you—whether it’s feedback, collaboration ideas, or just a friendly hello!

Disclaimer

This content has been generated with the assistance of AI. While I strive for accuracy and quality, please verify critical information independently.

Top comments (0)