• Home
  • Blogs
  • How to Build Scalable Web Apps with MongoDB, Express, React, and Node.js

How to Build Scalable Web Apps with MongoDB, Express, React, and Node.js

Unlock the secrets of scalable web apps! Master MongoDB, Express, React, and Node.js with our expert guide. Build robust applications effortlessly. Start your journey now!

Building a scalable web app can be a challenging and time-consuming task. With the right tools, tech stacks, and frameworks, however, it can be less daunting. 

In this article, we will show you how to build scalable web apps with MongoDB, Express, React, and Node.js, commonly known as the MERN stack. 

These technologies are among the most popular and widely used frameworks, and they all work together seamlessly to create robust and scalable web apps.

MongoDB

MongoDB is a powerful and widely used NoSQL database that provides high scalability and performance by breaking down data into collections and documents. 

One of the biggest advantages of using MongoDB is its ability to handle large volumes of data. Which makes it ideal for building scalable web apps. 

Here are the steps with code snippets to build scalable web apps with MongoDB:

Design your data model with scalability in mind

MongoDB is document-oriented, so you can store complex, nested data structures in a single document. 

It is important to design your data model in a way that won’t require frequent changes or have performance issues as the data grows.

// Define a schema for your data

const userSchema = new mongoose.Schema({

  name: String,

  email: String,

  age: Number

});

// Create a model from the schema

const User = mongoose.model(‘User’, userSchema);

Optimize queries for performance

MongoDB provides many indexing options and query tools that can help you optimize your queries for faster performance. 

You can use tools like explain() to evaluate your queries and see potential performance improvements.

// Create an index for faster query performance

userSchema.index({ email: 1 });

// Use explain() to evaluate query performance

User.find({ age: { $gt: 30 } }).explain();

Use sharding to distribute your data

MongoDB’s sharding feature allows you to horizontally partition your data across multiple servers, enabling you to scale your application horizontally as your data grows.

// Enable sharding in your MongoDB instance

sh.enableSharding(‘mydatabase’);

// Create a shard key for your collection

db.myCollection.createIndex({ country: 1, city: 1 });

// Shard your collection

sh.shardCollection(‘mydatabase.myCollection’, { country: 1, city: 1 });

Use replica sets for high availability

With replica sets, you can have multiple copies of your data across different servers, providing automatic failover when one server goes down.

// Create a replica set

rs.initiate();

// Add nodes to the replica set

rs.add(‘mongo1.example.com’);

rs.add(‘mongo2.example.com’);

// Configure your app to use a replica set connection string

const url = ‘mongodb://mongo1.example.com,mongo2.example.com/mydatabase?replicaSet=myReplicaSet’;

mongoose.connect(url);

Monitor and optimize your database performance

MongoDB provides many tools for monitoring and optimizing database performance, including the ability to generate performance metrics, query profiling, and more.

// Enable profiling to capture performance metrics

db.setProfilingLevel(2);

// Use the dbProfiler aggregation pipeline to analyze query performance

db.system.profile.aggregate([

  { $match: { op: { $eq: ‘query’ } } },

  { $group: { _id: ‘$query.$query._id’, count: { $sum: 1 }, time: { $sum: ‘$millis’ } } },

  { $sort: { count: –1 } }

]);

By following these steps and using the code snippets provided, you can use MongoDB to build scalable and performant web applications that can handle high traffic and large amounts of data.

Features and Benefits

MongoDB provides several capabilities and features that make it a popular choice for building scalable web apps. Some of the key features and benefits of MongoDB include:

  • High scalability and performance: MongoDB is designed to handle large volumes of data and provides high scalability and performance for web apps.
  • Flexible data model: MongoDB uses a flexible data model that allows you to store data in collections and documents, making it easy to work with complex data structures.
  • Rich query language: MongoDB provides a rich query language that allows you to search and manipulate data in powerful ways.
  • Automatic sharding: MongoDB supports automatic sharding, which allows you to distribute data across multiple machines for improved performance and scalability.

Express

Express is a popular and widely used web framework for Node.js that makes it easy to build powerful and scalable web apps. 

It provides a robust set of features that can help you build APIs, web applications, and more.

The code snippets below are designed to provide practical examples of how to implement the steps discussed. They can be used as a reference or starting point for your coding projects. 

Modular architecture using Express

Use a modular architecture to break your application into smaller, more manageable modules.

//Create an express app

const app = express();

// define routes

const routes = require(‘./routes’); // example route module

app.use(‘/routes’, routes);

// start server

const server = app.listen(3000, () => {

  console.log(‘Server is running on port’, server.address().port);

});

Middleware in Express

Use middleware to handle common tasks like authentication, logging, and error handling.

// custom middleware for logging

app.use((req, res, next) => {

  console.log(`${req.method} ${req.originalUrl}`);

  next();

});

// error handling middleware

app.use((err, req, res, next) => {

  console.error(err.stack);

  res.status(500).send(‘Something went wrong!’);

});

Routing in Express using Express Router

Optimize your application’s routing for better performance by using Express Router and handling routes in separate files.

// create an express router

const router = express.Router();

// define routes

router.get(‘/’, (req, res) => {

  res.send(‘Hello World!’);

});

router.get(‘/users’, (req, res) => {

  res.send(‘List of users’);

});

// mount router in main app

app.use(‘/api’, router);

Caching in Express using Redis

Use caching mechanisms to reduce the load on your database and speed up your application.

// create redis client

const redis = require(‘redis’);

const client = redis.createClient();

// set cache

app.get(‘/api/users’, (req, res) => {

  client.get(‘users’, (err, data) => {

    if (err) throw err;

    if (data !== null) {

      res.send(JSON.parse(data));

    } else {

      // fetch data from db

      User.find({}, (err, users) => {

        if (err) throw err;

        // cache data in redis for future use

        client.set(‘users’, JSON.stringify(users));

        res.send(users);

      });

    }

  });

});

Load balancing in Express using PM2

Implement load balancing to distribute traffic to multiple servers and improve the overall performance of your application.

// install pm2

npm install -g pm2

// start multiple instances of your app with pm2

pm2 start app.js -i max

// scale up or down as needed

pm2 scale app +5

pm2 scale app –3

Features and Benefits

Express provides a range of features and benefits that make it a popular choice for building robust and scalable web apps. Some of the key features and benefits of Express include:

  • Minimalist and flexible framework: Express is designed to be a minimalist and flexible framework that allows you to build web apps according to your specific needs and requirements.
  • Middleware support: Express provides support for middleware, which allows you to add custom functionality to your web apps.
  • Routing support: Express provides support for routing, which makes it easy to handle HTTP requests and responses in a structured and organized way.

React

React is a powerful and widely used JavaScript library for building user interfaces. It provides a declarative way of building UI components, which makes it easy to create reusable and scalable UI components.

By following the steps below, you can build scalable and performant web apps with React.

Use a modular architecture to break your application into smaller, more manageable components

In React, you can break your application into small, reusable components, each responsible for a single functionality. 

The components should be independent of each other and can be reused across your codebase. You can also use higher-order components to avoid code repetition and create more modular components.

import React from ‘react’;

// example component

const MyComponent = () => {

  return (

    <div>

      <h1>Hello World!</h1>

      <p>This is my first React component.</p>

    </div>

  )

};

export default MyComponent;

Optimize your components for performance by using stateless functional components and avoiding unnecessary re-renders.

Stateless functional components are simple components that don’t have any internal state. 

They are faster and more performant than class-based components because they don’t have any lifecycle methods or internal states that trigger component re-renders. 

You can also use the React.memo() function to prevent unnecessary renders of your components.

import React from ‘react’;

// example stateless functional component

const MyComponent = ({ name }) => {

  return (

    <div>

      <h1>Hello, {name}!</h1>

    </div>

  )

};

export default MyComponent;

Use a virtual DOM to reduce the number of actual DOM manipulations and improve performance.

React uses a virtual DOM to update the browser’s DOM only when necessary, thereby reducing the number of actual DOM manipulations needed. 

The virtual DOM is a lightweight representation of the actual DOM that React uses to apply updates to the browser’s DOM. 

You can use the React.createElement() method to create virtual DOM elements and update the virtual DOM using React’s state management features.

const element = React.createElement(‘div’, {}, [

  React.createElement(‘h1’, { key: ‘title’ }, ‘Welcome to my app!’),

  React.createElement(‘p’, { key: ‘content’ }, ‘This is some example content.’)

]);

ReactDOM.render(element, document.getElementById(‘root’));

Use a state management library like Redux for managing application state and improving scalability

Redux is a state management library that provides a predictable state management solution for your application. 

It helps you manage the data flow in your application and allows you to centralize the application’s state. 

By centralizing the application state, you can reduce the amount of boilerplate code needed and enhance the scalability of your codebase.

// create an action creator

const increment = () => ({ type: ‘INCREMENT’ });

// create a reducer

const counterReducer = (state = 0, action) => {

  switch (action.type) {

    case ‘INCREMENT’:

      return state + 1;

    default:

      return state;

  }

};

// create a store

import { createStore } from ‘redux’;

const store = createStore(counterReducer);

// use the store in your components

import { connect } from ‘react-redux’;

const MyComponent = ({ count, dispatch }) => {

  return (

    <div>

      <h1>Counter: {count}</h1>

      <button onClick={() => dispatch(increment())}>Increment</button>

    </div>

  )

};

const mapStateToProps = state => ({ count: state.counter });

export default connect(mapStateToProps)(MyComponent);

Use server-side rendering to improve initial page load time and improve search engine optimization (SEO)

Server-side rendering is a technique that renders your React components on the server before sending them to the client. 

This technique can improve page load times, especially on slow networks, and can also improve search engine optimization by providing search engines with a fully rendered HTML page.

// create a Next.js app

npm install –save next react react-dom

// create a pages directory and add a page to it

// example page in pages/index.js

import React from ‘react’;

const IndexPage = () => (

  <div>

    <h1>Welcome to my app!</h1>

    <p>This is a server-side rendered React application.</p>

  </div>

);

export default IndexPage;

// start the server

npm run dev

Features and Benefits

React provides a range of features and benefits that make it a powerful and versatile library for building scalable web apps. Some of the key features and benefits of React include:

  • Declarative programming model: React provides a declarative programming model that makes it easy to create UI components that are reusable and easy to understand.
  • Component-based architecture: React uses a component-based architecture that allows you to build complex UI components in a modular and reusable way.
  • Virtual DOM: React uses a virtual DOM, which helps to improve performance by reducing the number of updates required for UI elements.

Node.js

Node.js is a powerful and widely used JavaScript runtime that allows you to run JavaScript code on the server side. 

It provides a powerful set of features that can help you build server-side applications and APIs.

Here are the steps that you need to follow to create your web app using Node.js:

Modular architecture using Node.js modules

Use a modular architecture to break your application into smaller, more manageable modules.

// example module

function hello() {

  console.log(‘Hello World!’);

}

module.exports = hello;

Non-blocking I/O in Node.js using asynchronous functions

Use non-blocking I/O to allow your application to handle many concurrent requests without being blocked by I/O operations.

// example asynchronous function

function doAsync(callback) {

  // do something async

  setTimeout(() => {

    callback(null, ‘Done!’);

  }, 1000);

}

// using asynchronous function

doAsync((err, result) => {

  if (err) console.error(err);

  console.log(result);

});

Routing in Node.js using Router

Optimize your application’s routing for better performance by using a Router and handling routes in separate files.

// create a router instance

const router = require(‘express’).Router();

// define routes

router.get(‘/’, (req, res) => {

  res.send(‘Hello World!’);

});

router.get(‘/users’, (req, res) => {

  res.send(‘List of users’);

});

// mount router in main app

const app = require(‘express’)();

app.use(‘/api’, router);

Caching in Node.js using Redis

Use caching mechanisms to reduce the load on your database and speed up your application.

// create redis client

const redis = require(‘redis’);

const client = redis.createClient();

// set cache

app.get(‘/api/users’, (req, res) => {

  client.get(‘users’, (err, data) => {

    if (err) throw err;

    if (data !== null) {

      res.send(JSON.parse(data));

    } else {

      // fetch data from db

      User.find({}, (err, users) => {

        if (err) throw err;

        // cache data in redis for future use

        client.set(‘users’, JSON.stringify(users));

        res.send(users);

      });

    }

  });

});

Load balancing in Node.js using PM2

Implement load balancing to distribute traffic to multiple servers and improve overall performance of your application.

// install pm2

npm install -g pm2

// start multiple instances of your app with pm2

pm2 start app.js -i max

// scale up or down as needed

pm2 scale app +5

pm2 scale app –3

Features and Benefits

Node.js provides a range of features and benefits that make it a powerful and flexible platform for building scalable web apps. 

Some of the key features and benefits of Node.js include:

  • Non-blocking I/O: Node.js uses non-blocking I/O, which makes it possible to handle large volumes of requests and responses in a scalable and efficient way.
  • Extensive library support: Node.js provides access to a wide range of libraries and frameworks, which makes it easy to build web apps according to your specific needs and requirements.
  • Cross-platform support: Node.js is designed to be cross-platform, which makes it possible to write and run your web apps on a wide range of platforms and operating systems.

Conclusion 

In this article, we have explored how to build a scalable web application using the MERN stack. We have covered the steps involved in designing the application architecture, setting up the development environment, and building the backend with Node.js and Express. 

And setting up the database with MongoDB, building the frontend with React, and connecting the backend and frontend of the application. 

By following these steps, you can build a scalable web application that can handle high traffic and load.  

Similarly, we also gave you a step-by-step guide on all 4 technologies within the MERN stack too to make your web app using them separately.

Looking for Top Talent?

We create transparency for a global economy built on blockchains.

Mezino @2022 Allrights.reserved

A team of blockchain enthusiasts