Setup to create an Electron app using create-react-app



I assume basic familiarity with NodeJS as well as the command line.

You also need to have Node.js and npm installed on your computer. You can visit the Node.js website to view installation instructions for your operating system. npm comes bundled with Node, so once you install Node, you’ll have access to the npm command too.

The versions I used while building this project are as follows:

  1. Node.js - v10.15.3
  2. npm - 6.13.4

Use these commands to check your node and npm versions

node -v
npm -v

Create a new react app

To create a project called awesome-app, run this command:

npx create-react-app awesome-app

Then, navigate into the create app using cd awesome-app

Install electron and electron-builder

Electron builder is a packaging tool for electron project.

npm install electron
npm install --save-dev electron-builder

Install foreman

Foreman is a manager for Procfile-based applications. Its aim is to abstract away the details of the Procfile format, and allow you to either run your application directly or export it to some other process management format. (source: npm)

npm install foreman --save-dev

I generally use it as dev-dependency, but you can install it globally. If you install foreman globally you can use it in any project without installing as dependency.

Setup Procfile for foreman

Create a Procfile in the root of your source code (where package.json resides)

react: npm run react-start
electron: npm run electron-start

Setup npm scripts

"scripts": {
  "start": "nf start -p 3000",
  "build": "react-scripts build",
  "test": "react-scripts test --env=jsdom",
  "eject": "react-scripts eject",
  "electron": "electron .",
  "electron-start": "node src/start-react",
  "react-start": "BROWSER=none react-scripts start",
  "pack": "build --dir",
  "dist": "npm run build && build",
  "postinstall": "install-app-deps"

On windows the environment variables might not work this way: On Windows you might need to have a .env file with BROWSER=none in it as environment variables do not work like in Linux/macOS.

To know more, read Inline environment variables in CLI.

Setup package.json

  "homepage": "./",
  "main": "src/electron-main.js",
  "build": {
  "appId": "com.example.electron-react",
  "win": {
    "iconUrl": "https://awsm.page/assets/apple-touch-icon-180x180.png"
  "directories": {
    "buildResources": "public"

Some starter code

You need to have some starter files

  1. src/start-react.js
  2. src/electron-main.js
// script to wait till react app start on http://localhost:3000
const net = require('net');
const port = process.env.PORT ? process.env.PORT - 100 : 3000;

process.env.ELECTRON_START_URL = `http://localhost:${port}`;

const client = new net.Socket();

let startedElectron = false;
const tryConnection = () =>
  client.connect({ port: port }, () => {
    if (!startedElectron) {
      console.log('starting electron');
      startedElectron = true;
      const exec = require('child_process').exec;
      exec('npm run electron');


client.on('error', error => {
  setTimeout(tryConnection, 1000);
// This is a file for main process
const {app, BrowserWindow} = require('electron')
const path = require('path')

let mainWindow

const startUrl =
  process.env.ELECTRON_START_URL ||
    pathname: path.join(__dirname, '/../build/index.html'),
    protocol: 'file:',
    slashes: true

function createWindow () {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600


  mainWindow.on('closed', function () {
    mainWindow = null

app.on('ready', createWindow)

app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit()

app.on('activate', function () {
  if (mainWindow === null) createWindow()

Start the app

To start the app, use the command

npm start

This post is heavily inspired by:

Frequently asked questions

Getting error for "window.require" inside electron app?

This error is related to electron API rather than your setup. To use 'require' and other node functions inside your 'renderer process', you need to enable the 'nodeIntegration' by setting it when you create a new BrowserWindow.

Last Updated on

Next Post: GraphProtocol: TS2322 null assignment in Subgraph →