DEV Community

Cover image for Running React and Express with concurrently
Matt Angelosanto for LogRocket

Posted on • Originally published at blog.logrocket.com

Running React and Express with concurrently

Written by Vijit Ail✏️

In modern web development, it’s common to build full-stack applications that consist of a frontend framework, like React, and a backend framework, like Express.js. In this model, React contributes a robust and interactive user interface, while Express handles server-side logic, data storage, and API endpoints.

To efficiently develop and test these applications, it’s essential to run React and Express servers simultaneously. One option is to manually start each server using separate terminal windows or tabs, but this approach is cumbersome and inefficient. An option is to use the concurrently or npm-run-all  CLI tools designed to run multiple npm-scripts in parallel or sequentially.

In this article, we’ll explore how to set up and run React and Express together using the concurrently command-line tool to achieve streamlined development workflow, efficient management of frontend-backend integration, and enhanced productivity.

Jump ahead:

Getting to know concurrently

The concurrently command-line tool allows you to run multiple commands or scripts simultaneously from a single terminal window, providing a convenient way to manage and orchestrate different processes within a development environment. concurrently is often used in the context of running React and Express together to streamline the development workflow.

Here’s how concurrently simplifies the development process:

  • Single command execution: Allows you to start both the React frontend and Express backend servers with a single command. This simplifies the setup process and saves time and effort
  • Streamlined development workflow: Enables automatic restart of both servers whenever changes are made to the frontend or backend code. Eliminating the need to manually stop and restart each server separately provides a seamless development experience and faster iteration
  • Consolidated console output: Merges the console output from multiple processes into a single terminal window. Viewing logs, and errors and debugging information from React and Express simultaneously makes it easier to track and debug issues during development

concurrently supports running multiple scripts or commands in parallel. This means you can define separate scripts for starting the React and Express servers in your package.json file, and concurrently will execute them together.

For example, in your package.json file, you can define scripts, like so:

"scripts": {
  "start:frontend": "react-scripts start",
  "start:backend": "node server.js",
  "start": "concurrently \"npm run start:frontend\" \"npm run start:backend\""
}
Enter fullscreen mode Exit fullscreen mode

The start script uses concurrently to execute both the frontend and backend scripts simultaneously. When you run the npm start command, concurrently will start the React and Express servers, allowing them to work together seamlessly.

Additionally, concurrently provides options to customize behavior, such as controlling the number of processes running simultaneously, specifying custom names for processes, and more. These options allow you to fine-tune the execution of multiple scripts based on your specific requirements.

Setting up the React frontend

To set up the React frontend, open your terminal, navigate to the desired directory for your project, and run the following commands:

> yarn create react-app concurrently-app
> cd concurrently-app
> mkdir server
> touch server/index.js
Enter fullscreen mode Exit fullscreen mode

The above code creates a React app, as well as a server/index.js file inside the root directory for the backend application.

Setting up the Express.js backend

Next, install the express and nodemon packages. Nodemon is a tool that automatically restarts the server whenever changes are made, facilitating a smoother development experience:

> yarn add express
> yarn add -D nodemon
Enter fullscreen mode Exit fullscreen mode

In the server/index.js file add the following code:

// server/index.js

const express = require("express");
const users = require("./users.json");

const app = express();

const PORT = 3001;

app.get("/api/users", (req, res) => {
  return res.json(users);
});

app.listen(PORT, () => console.log(`Listening on port ${PORT}`));
Enter fullscreen mode Exit fullscreen mode

The code sets up an Express server that listens on port 3001. The server has a single API endpoint, /api/users, that responds with JSON data from the users.json file. When a request is made to the /api/users endpoint, the server sends back the JSON data containing user information.

Integrating the React component with the API

Now let’s have a look at the React component:

// src/App.js

import { useEffect, useState } from "react";
import "./App.css";

function App() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch(`/api/users`)
      .then((res) => res.json())
      .then((data) => setUsers(data));
  }, []);

  return (
    <div className="App">
      <h1>Users</h1>
      {users.map((user) => (
        <p key={user.id}>{user.name}</p>
      ))}
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

The <App /> component fetches data from the backend, using the fetch API and the /api/users endpoint, and then renders the user names received from the backend API. The useEffect Hook is used to fetch the data when the component mounts. The fetched data is stored in the users state variable using the useState Hook.

Now, add the following code to your package.json file:

// package.json

{
...
  "scripts": {
    ...
    "start:frontend": "react-scripts start",
    "start:backend": "nodemon server/index.js"
  },
  "proxy": "http://localhost:3001"
}
Enter fullscreen mode Exit fullscreen mode

The proxy field specifies the proxy server that will be used in development. It is set to http://localhost:3001, meaning any API requests made from the React frontend to endpoints starting with /api will be automatically proxied to the Express backend server running on port 3001.

Installing and configuring concurrently

It’s time to integrate the concurrently CLI. Begin by installing concurrently as a development dependency in your project. Open your terminal and run the following:

> yarn add -D concurrently
Enter fullscreen mode Exit fullscreen mode

This command installs concurrently and makes it available for use in your project. Next, configure the "scripts" section of your project’s package.json file to use concurrently:

"scripts": {
  ...
  "start:frontend": "react-scripts start",
  "start:backend": "nodemon server/index.js",
  "start": "concurrently \"npm run start:frontend\" \"npm run start:backend\""
},
Enter fullscreen mode Exit fullscreen mode

In the above configuration, the start:frontend script runs the React frontend using react-scripts start, and start:backend script starts the Express backend using nodemon server/index.js. In the start script, Concurrently is used to execute both the start:frontend and start:backend scripts simultaneously.

After running the npm run start command in your terminal, you should see the following output: Terminal Output After Installing Concurrently Here’s what you’ll see in the browser: Browser Output After Installing Concurrently As you can see in the above terminal screen, it can be challenging to identify the source of console output and to distinguish between the frontend and backend processes. The basic configuration serves well for simple setups and fast initiation, but concurrently provides additional customization and flexibility options to enhance the development experience.

To enable a custom configuration, modify the "start" script according to the following snippet:

"scripts": {
    ...
    "start": "concurrently -n \"FRONTEND,BACKEND\" -c \"red,blue\" -p \"[{name}]\" \"npm run start:frontend\" \"npm run start:backend\""
  }
Enter fullscreen mode Exit fullscreen mode

Now, when you run the npm run start command, you’ll see much clearer identification and differentiation between the frontend and backend processes in the console output: Frontend Backend Process Output Concurrently Let’s take a closer look at the command options:

  • -n: Specifies the names of the processes, in this case, FRONTEND and BACKEND are used; allows us to customize the names of the concurrent processes for better clarity in the console output
  • -c: Specifies the colors of the processes, in this case, red and blue are used; helps differentiate the console output of the two processes for easier identification
  • -p: Specifies the pattern for the console output, in this case, [{name}] is used with the name specified by the -n option; this pattern helps distinguish the output of each process

The custom configuration provides a foundation for scalability and adaptability. As your application grows, you can easily modify the names, colors, and patterns to accommodate additional concurrent processes or specific requirements. It allows for easy customization based on your project's needs, making it suitable for more advanced or complex applications.

Conclusion

Running React and Express with concurrently greatly simplifies the development process and enhances workflow when building full-stack applications. Developers can use concurrently to seamlessly run both the frontend and backend servers simultaneously from a single terminal window. Whether using a basic configuration or opting for a more customized setup, concurrently offers flexibility and convenience.

Devs can leverage the capabilities of concurrently to effectively construct and test full-stack applications, guaranteeing smooth integration between the React frontend and Express backend. This streamlined approach enhances productivity, enables rapid iteration, and ultimately leads to better DevEx.


Get set up with LogRocket's modern React error tracking in minutes:

  1. Visit https://logrocket.com/signup/ to get an app ID.
  2. Install LogRocket via NPM or script tag. LogRocket.init() must be called client-side, not server-side.

NPM:

$ npm i --save logrocket 

// Code:

import LogRocket from 'logrocket'; 
LogRocket.init('app/id');
Enter fullscreen mode Exit fullscreen mode

Script Tag:

Add to your HTML:

<script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
<script>window.LogRocket && window.LogRocket.init('app/id');</script>
Enter fullscreen mode Exit fullscreen mode

3.(Optional) Install plugins for deeper integrations with your stack:

  • Redux middleware
  • ngrx middleware
  • Vuex plugin

Get started now

Top comments (1)

Collapse
 
khairunnisaas profile image
Khairunnisaas

very insteresting post! but i do have 1 question. is your frontend project folder and backend project folder become 1?