Structure a Flask React Monorepo
Tags: python, flask, javascript, react
Published: 2019-06-08 17:58:48

---
title: Structure a Flask React Monorepo
published: true
tags: [python, flask, javascript, react]
canonical_url: https://warrenwong.org/structure-a-flask-react-monorepo/
cover_image: https://warrenwong.org/static/ebbcb1d8d9588fbcccc93f9620bba320/96726/ashim-d-silva-106275-unsplash.jpg
---

This is my project structure for a Flask server and React client residing in the same git repository. It's fairly similar to the many NodeJS, React [monorepos](https://en.wikipedia.org/wiki/Monorepo) out there where the server code will be in the `server` subdirectory and the client code will reside in the `client` subdirectory.

First, let's start by creating the project directory and intialize the git repository:

```bash
mkdir flask-react-monorepo
cd flask-react-monorepo
git init
```

Let's create a virtual environment for the repo with [`venv`](https://docs.python.org/3/library/venv.html) and place it in the `venv` directory inside the project. We will want to add this to our `.gitignore` file also. Once we have our virtual environment set up, we'll need to let our system know to use it.

```bash
python -m venv venv
echo venv/ > .gitignore
source venv/bin/activate
```

Let's install our dependencies, first for Python, then keep a list of the dependencies in a file called `requirements.txt`.

```bash
pip install Flask
pip freeze > requirements.txt
```

`requirements.txt` (your versions may vary)

```
Click==7.0
Flask==1.0.3
itsdangerous==1.1.0
Jinja2==2.10.1
MarkupSafe==1.1.1
Werkzeug==0.15.4
```

The canonical way to structure flask apps have a Python package named whatever the actual app is supposed to be within a subdirectory. Check out the Flask tutorial [here](http://flask.pocoo.org/docs/1.0/tutorial/layout/) for more details.

For now, let's call the Flask server `server`. It can easily be `api` or something else you prefer.

```bash
mkdir server
```

For our Flask setup to work, we will need to create a file named `setup.py` in the root of our project directory:

`setup.py`

```python
from setuptools import setup

setup(
    name='server',
    packages=['server'],
    include_package_data=True,
    install_requires=['flask']
)
```

Now, let's just set up a simple Flask app in the `server` Python package by having an ` __init__.py` file in our `server` directory.

`server/ __init__.py`

```python
from flask import Flask

app = Flask( __name__ )

@app.route('/')
def index():
    return 'Hello, World!'
```

Now comes for the fun part of integrating our JavaScript client. I'll simply use `create-react-app` for this, but you can pretty much replace this with any front end framework or CLI tools you like.

From the project root:

```bash
create-react-app client
```

Now, we can go and type `FLASK_APP=server flask run` from the project root to run our development server and, from another terminal, run `yarn start` from the `client` directory to run the development client, but that's just 1 too many steps for me.

To streamline the development process, I'll also use `yarn` in the project root and install the [`concurrently`](https://www.npmjs.com/package/concurrently) package.

From the root directory:

```bash
yarn init
yarn add -D concurrently
echo node_modules/ >> .gitignore
```

Now, let's add some scripts to the `package.json` file `yarn init` generated. I want `yarn client` to run the client development server and `yarn server` to run the backend development server. I also want to call `yarn start` from the root to run both concurrently.

```json
{
  "name": "flask-react-monorepo",
  "version": "1.0.0",
  "main": "index.js",
  "author": "Warren Wong <me@warrenwong.org>",
  "license": "MIT",
  "devDependencies": {
    "concurrently": "^4.1.0"
  },
  "scripts": {
    "start": "concurrently \"yarn client\" \"yarn server\"",
    "client": "cd client && yarn start",
    "server": "FLASK_APP=server flask run"
  }
}
```

If everything works out, your back end will be on port [5000](http://localhost:5000) and your client will be on port [3000](http://localhost:3000) by default.