Build a React based Electron app

Build a React based Electron app

Desktop Applications With React.js and Electron

Build a React based Electron app

Electron + React app template

But how can we trying to start by known command line tools (create-react-app)?

I will create Electron + React app with yarn command, but it's comfortable to use npm command too.

Create Electron + React project

Prerequisite:

If you want to use yarn, you should install yarn before use.

Steps

  1. Run create-react-app to generate a basic React application
  2. Install dependencies packages
  3. Add public/electron.js as startup entry target.
  4. Add code into public/electron.js for running electron app.
  5. Add main entry to package.json for public/electron.js.
  6. Edit package.json scripts section, add some scripts command for run electron.
  7. Run script, should see electron app window.

Sample code

Create React project

Step 1. Generate a basic React application

I create React app with commands at below. I would like to use typescript template, but you could create without use typescript template.

npx create-react-app my-electron-app --template typescript

or

yarn create react-app my-electron-app --template typescript

Step 2. Install dependencies

In this step I will install some packages useful for electron + react development environment.

  • electron and electron-builder are require for electron app.
  • concurrently for execute commands in same time. This is for runing react-scripts and electron.
  • wait-on for wait react application has started, then start the electron.
npm install concurrently electron electron-builder wait-on cross-env electron-is-dev --save-dev

or

yarn add --dev concurrently electron electron-builder wait-on cross-env electron-is-dev

Step 3. Add public/electron.js and Step 4. Add code into electron.js

public/electron.js

const electron = require("electron");
const {app, BrowserWindow} = electron;
const path = require("path");
const isDev = require("electron-is-dev");

let mainWindow;

function createWindow() {
    mainWindow = new BrowserWindow({
        title: 'my-electron-app',
        width: 900,
        height: 680,
        webPreferences: {
            nodeIntegration: true,
        },
    });
    mainWindow.loadURL(
        isDev
            ? "http://localhost:3000"
            : `file://${path.join(__dirname, "../build/index.html")}`
    );
    mainWindow.on("closed", () => (mainWindow = null));
    // Open the DevTools.
    if (isDev) {
        mainWindow.webContents.openDevTools({mode: 'detach'});
    }
}

app.on("ready", createWindow);
app.on("window-all-closed", () => {
    // On macOS it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== "darwin") {
        app.quit();
    }
});
app.on("activate", () => {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (mainWindow === null) {
        createWindow();
    }
});

Step 5. Add main entry into package.json

Add below into package.json

package.json

{
  ...
  "description": "<your project description>",
  "author": "<author of app>",
  "build": {
    "appId": "<com.your_app>"
  },
  "main": "public/electron.js",
  "homepage": "./",
  ...
}
  • description: app description
  • author: your information
  • build: Electron-Builder Configuration
  • appId: your app ID
  • main: electron entry target
  • homepage: startup path

Step 6. Add scripts for run and build electron app

Update scripts sections in packages.json

  "scripts": {
    "react-start": "react-scripts start",
    "react-build": "react-scripts build",
    "react-test": "react-scripts test --env=jsdom",
    "react-eject": "react-scripts eject",
    "electron-build": "electron-builder",
    "release": "yarn react-build && electron-builder --publish=always",
    "build": "yarn react-build && yarn electron-build",
    "start": "concurrently \"cross-env BROWSER=none yarn react-start\" \"wait-on http://localhost:3000 && electron .\""
  },

In development environment will use react-scripts start to start web server for react application. By default, react-scripts start execute React application on port 3000. In start has wait-on http://localhost:3000 to ensure React application website is ready, after that start to run electron.

You could change port, If your port was used. See how to change port on development environment.

Step 7. Run electron app

npm run start

# or

yarn start

build

npm run build

# or

yarn build

After build success will generate files in dist folder.

Appendix

How to change port on development environment use

This example is change to use port 3003:

  1. assign port Environment in "react-start"
    "scripts": {
     "react-start": "PORT=3003 react-scripts start",
     ...
    },
    
  2. Edit port in "start"
    {
    ...
    "scripts": {
     ...
     "start": "concurrently \"cross-env BROWSER=none yarn react-start\" \"wait-on http://localhost:3003 && electron .\""
    },
    ...
    }
    
  3. Edit port in public/electron.js
    function createWindow() {
     ...
     mainWindow.loadURL(
         isDev
             ? "http://localhost:3003"
             : `file://${path.join(__dirname, "../build/index.html")}`
     );
     ...
    }
    

Multi platform build

Add -mwl for build MacOS, Windows and Linux apps.

  "scripts": {
    ...
    "electron-build": "electron-builder -mwl",
    ...
  },

References