Set up a React app with a Node.js server proxy
Tags: react, javascript, node, express
Published: 2018-10-10 03:01:44

---
title: Set up a React app with a Node.js server proxy
published: true
tags: react, javascript, node, express
canonical_url: https://www.twilio.com/blog/react-app-with-node-js-server-proxy
cover_image: https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/s2-0wBJwglXgY-J1SEQqjxzePIRwX0hewng9LVRP7tyf2K.width-808.png
---

_Create React App_ is a great tool for getting a React application up and running. It's a little less clear when you're building or prototyping an application that requires a server side component, like [generating access tokens](https://www.twilio.com/docs/iam/access-tokens) for Twilio [Video](http://twilio.com/docs/video) or [Chat](https://www.twilio.com/docs/chat), though. I've found it easiest to work with a server within the same project so that you can start everything up with one command.

By the end of this post you will learn how to set up an [Express](http://expressjs.com/) server that runs alongside a React app. If you can't wait then you can jump straight into [the starter project on GitHub](https://github.com/philnash/react-express-starter).

### How it works

There is an [option that you can set in _Create React App_'s `package.json`](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#proxying-api-requests-in-development) that proxies non `text/html` requests through to an alternative back end. You can use this feature to proxy to applications running elsewhere, but today we want to be able to run a server within the React project itself.

We'll pull together a few npm modules that will make it possible to run one command to run our React app and an Express server at the same time so we can proxy to it.

### Getting started

To follow along with the rest of this post, you will need Node.js and npm installed.

Start by creating a new React app with _Create React App_. Did you know, you don't have to globally install the `create-react-app` package to do this? Instead, you can run:

```bash
npm init react-app MyNewApp
cd MyNewApp
```

Under the hood, [`npm init` takes an initializer name, prepends `create-` to it and uses npx to install and run the command](https://docs.npmjs.com/cli/init#description).

Run the new React application to make sure it was generated properly.

```bash
npm start
```

If you see a spinning React logo, then we're good to go.

### Adding a server

We'll add our server dependencies to the `devDependencies` of our React app as they aren't part of building the front end.

Stop the server with `Cmd/Ctrl + C` and use `npm` to install Express and Body Parser:

```bash
npm install express body-parser --save-dev
```

Add the following dependencies to help us run the front end and server together:

- [node-env-run](https://www.npmjs.com/package/node-env-run) - [Dominik's module for loading environment variables](https://www.twilio.com/blog/2017/08/working-with-environment-variables-in-node-js.html) from a config file in development
- [nodemon](https://www.npmjs.com/package/nodemon) - for automatically restarting the server when it changes
- [npm-run-all](https://www.npmjs.com/package/npm-run-all) - for running multiple npm scripts at the same time
- [express-pino-logger](https://github.com/pinojs/express-pino-logger) and [pino-colada](https://github.com/lrlna/pino-colada) - for better server logging

```bash
npm install node-env-run nodemon npm-run-all express-pino-logger pino-colada --save-dev
```

Create a file called `.env` in the project directory to store our environment variables. We don't need to add anything to it just yet, but it will be useful later for including any credentials we need for the server, like API keys.

Next, in the project directory create a new directory called `server` and a `server/index.js`file. We'll create a small application that we can test with. Add the following code in `server/index.js`:

```javascript
const express = require('express');
const bodyParser = require('body-parser');
const pino = require('express-pino-logger')();

const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(pino);

app.get('/api/greeting', (req, res) => {
  const name = req.query.name || 'World';
  res.setHeader('Content-Type', 'application/json');
  res.send(JSON.stringify({ greeting: `Hello ${name}!` }));
});

app.listen(3001, () =>
  console.log('Express server is running on localhost:3001')
);
```

Open `package.json` and in the `"scripts"` object add a new script to run the server using `node-env-run` and `nodemon`:

```json
"scripts": {
    // other scripts
    "server": "node-env-run server --exec nodemon | pino-colada"
  },
```

Test that the server is running correctly by running the script:

```bash
npm run server
```

Open [http://localhost:3001/api/greeting](http://localhost:3001/api/greeting) to test. You should see a JSON response with a "Hello World!" greeting. Try adding a query parameter called `name` to the URL and see what you get.

### Running the server and the React app

To run both the server and React application at the same time we need to add a couple more things to `package.json`.

First, we are going to set up the proxy to our server. Add the `"proxy"` key to `package.json`. We've already set our server to run on port 3001, so point the proxy at localhost:3001.

```json
"proxy": "http://localhost:3001"
```

We need a script to run both the server and the front end at the same time. We will use `npm-run-all` for this. Since we are going to be running two scripts at the same time we want to use the parallel mode. `npm-run-all` gives us a handy shortcut for this with the `run-p` command.

Add the following to the `"scripts"` section in `package.json`:

```json
"scripts": {
    // other scripts
    "server": "node-env-run server --exec nodemon",
    "dev": "run-p server start"
  },
```

Run `npm run dev` and both the React application and the server will start up. However, we now can't load localhost:3000/api/greeting in the browser because the _Create React App_ proxy will just respond with the base HTML.

Let's test it from within a component in our React app instead.

### Using the proxied server from React

We're going to add a form to the `App` component that will use the `/api/greeting` component to form a greeting and show it on the page. Add the following constructor and functions to the App component in `src/App.js`:

```jsx
class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: '',
      greeting: ''
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({ name: event.target.value });
  }

  handleSubmit(event) {
    event.preventDefault();
    fetch(`/api/greeting?name=${encodeURIComponent(this.state.name)}`)
      .then(response => response.json())
      .then(state => this.setState(state));
  }
```

And add this form to the JSX in the `render` function:

```jsx
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <form onSubmit={this.handleSubmit}>
            <label htmlFor="name">Enter your name: </label>
            <input
              id="name"
              type="text"
              value={this.state.name}
              onChange={this.handleChange}
            />
            <button type="submit">Submit</button>
          </form>
          <p>{this.state.greeting}</p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
      </div>
    );
  }
```

Open the React app in the browser, fill in your name and submit. The greeting shows that your React app is now talking to your proxied server.

### This is only the start

_Create React App_ does a great job of getting a React application started, but if you need a server side component too, it can be fiddly. In this post you've seen how to use the `proxy` option and run an Express server alongside using tools like `npm-run-all`.

You can check out all the code from this post in [this GitHub repo](https://github.com/philnash/react-express-starter) and use it as a jumping off point if you want to build a React app with an Express API. As a bonus, if you want to create a [Twilio Video](https://www.twilio.com/docs/video) or [Twilio Chat](https://www.twilio.com/docs/chat) application with React, [the Twilio branch](https://github.com/philnash/react-express-starter/tree/twilio) is set to return [access tokens](https://www.twilio.com/docs/iam/access-tokens) for either. Just follow the instructions in [the README](https://github.com/philnash/react-express-starter/blob/twilio/README.md#access-token-endpoints).

Using [this template](https://github.com/philnash/react-express-starter), building React applications backed by an Express server is quicker and easier. I hope it gives you a good platform for building your own ideas; I can't wait to see what you build!