Home/Blog/Getting Started with React and Electron

Getting Started with React and Electron

Set up a React app inside Electron, package it for desktop, and add routing.

reactelectronjavascriptdesktop

In this tutorial, you will set up a React app to run inside Electron and package it for desktop. This is useful when you want to reuse React skills and components in a desktop app.

This guide assumes Node.js and npm are already installed.

Step 1: Create a React app

Create a new React app and start the development server:

npx create-react-app react-elec-demo
cd react-elec-demo
npm run start

You should see the default React app in your browser before adding Electron.

React app running in the browser

Step 2: Add an Electron entrypoint

Create main.js in the project root:

const path = require("path");
const { app, BrowserWindow } = require("electron");

const createWindow = () => {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
  });

  if (app.isPackaged) {
    win.loadFile(path.join(__dirname, "./build/index.html"));
    return;
  }

  win.loadURL("http://localhost:3000");
};

app.whenReady().then(() => {
  createWindow();
});

Then install the packages used for local Electron development:

npm install --save-dev electron wait-on concurrently

Step 3: Update package.json for local development

Add Electron as the app entrypoint and update the scripts:

{
  "main": "main.js",
  "homepage": ".",
  "scripts": {
    "start:react": "PORT=3000 react-scripts start",
    "start:electron": "electron .",
    "start": "concurrently \"npm run start:react\" \"wait-on http://localhost:3000/ && npm run start:electron\"",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject-react": "react-scripts eject"
  }
}

Now npm run start will open the React app inside an Electron window.

Step 4: Package the app for production

Install Electron Forge and import its config:

npm install --save-dev @electron-forge/cli
npm exec --package=@electron-forge/cli -c "electron-forge import"

Then update your scripts so the React build runs before packaging:

{
  "scripts": {
    "start:react": "PORT=3000 react-scripts start",
    "start:electron": "electron .",
    "start": "concurrently \"npm run start:react\" \"wait-on http://localhost:3000/ && npm run start:electron\"",
    "start:forge": "electron-forge start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "package": "npm run build && electron-forge package",
    "make": "npm run build && electron-forge make"
  }
}

Build the packaged app:

npm run package

This creates the React production build in build/ and the packaged Electron app in out/.

Step 5: Add multiple routes

Install React Router:

npm install react-router-dom

Update src/index.js to wrap the app with HashRouter:

import React from "react";
import ReactDOM from "react-dom/client";
import { HashRouter } from "react-router-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <HashRouter>
      <App />
    </HashRouter>
  </React.StrictMode>
);

reportWebVitals();

Then update src/App.js with a few routes:

import { Link, Route, Routes } from "react-router-dom";
import "./App.css";

function Home() {
  return (
    <section>
      <h1>Home</h1>
      <p>This is the default Electron route.</p>
    </section>
  );
}

function Settings() {
  return (
    <section>
      <h1>Settings</h1>
      <p>Put app preferences and local configuration here.</p>
    </section>
  );
}

function About() {
  return (
    <section>
      <h1>About</h1>
      <p>This page is rendered through React Router inside Electron.</p>
    </section>
  );
}

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <nav className="App-nav">
          <Link to="/">Home</Link>
          <Link to="/settings">Settings</Link>
          <Link to="/about">About</Link>
        </nav>

        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/settings" element={<Settings />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </header>
    </div>
  );
}

export default App;

Use npm run start again and confirm the routes render correctly inside Electron.

Multiple routes inside the Electron app

Conclusion

You now have a React app running inside Electron with a production packaging flow and client-side routing. From here, you can add native desktop features or package installers for your target platforms.