Convert a React app to a Desktop app with Electron

Go to your react project and install Electron:

yarn add --dev electron @types/electron electron-packager 

Rename React's webpack.config.js to webpack.react.config.js

Create a new file webpack.electron.config.js with:

./webpack.electron.config.js
const path = require("path"); const app_dir = __dirname + '/src'; const config = { mode: 'development', entry: app_dir + '/electron.ts', target: 'electron-main', output: { path: __dirname + '/dist', filename: 'electron-app.js', }, module: { rules: [{ test: /\.tsx?$/, loader: "ts-loader", exclude: /(node_modules|bower_components)/ }] }, resolve: { extensions: [".ts", ".tsx", ".js", ".jsx"] } }; module.exports = config;

Inside the src folder, add a file electron.ts:

import { app, BrowserWindow } from 'electron';
import * as path from 'path';
import * as url from 'url';

let mainWindow: Electron.BrowserWindow | null;

function isDev() {
  return process.argv[2] == '--dev';
}

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    // maxHeight:600,
    // maxWidth:600,
    // minHeight:400,
    // minWidth:400,
    // backgroundColor:'#7B435B'

    webPreferences: {
      nodeIntegration: true,
    },
  });

  if (isDev()) {
    mainWindow.loadURL(`http://localhost:8080`);
    // mainWindow.webContents.openDevTools()
  } else {
    mainWindow.loadURL(
      url.format({
        pathname: path.join(__dirname, 'index.html'),
        protocol: 'file:',
        slashes: true
      })
    );
  }

  mainWindow.on('closed', () => {
    mainWindow = null;
  });
}

app.on('ready', createWindow);

app.on("window-all-closed", () => {
  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 (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});

Then, update package.json with:

  "scripts": {
    "clean": "rm -rf dist/*",
    "build": "webpack --config webpack.react.config.js",
    "dev": "webpack serve --config webpack.react.config.js",
    "dev:electron": "webpack --config webpack.electron.config.js --mode development && electron ./dist/electron-app.js --dev",
    "build:electron": "webpack --config webpack.electron.config.js",
    "deploy": "electron-packager ./dist app-name --overwrite --asar=false --platform=linux --arch=x64 --prune=true --out=release-builds",
    "deploy-macos": "electron-packager ./dist app-name --overwrite --asar=false --platform=darwin --arch=x64 --prune=true --out=release-builds"
    }

Run yarn build and yarn build:electron

Then open ./dist/index.html and replace:

<script defer src="/app.js"></script></body>

with:

<script defer src="./app.js"></script></body>

and create ./dist/package.json

{
 "name": "app-name",
 "version": "0.1.0",
 "main": "electron-app.js"
}

Then run yarn deploy and go to ./release-builds/app-name-linux-x64/ and run ./app-name or yarn deploy-macos and run the app at ./release-builds/app-name-darwin-x64/app-name.app/...

Full source code here