loading...
Cover image for How to create an electron-forge project with React, Typescript and HMR

How to create an electron-forge project with React, Typescript and HMR

raphaelbadia profile image Raphaël Badia Updated on ・3 min read

As a react developer, I've always been used to magic CLIs that scaffold projects with everything included, such as Next.js or create-react-app. I don't think I ever setup react from scratch, but there is no electron-forge template for that, so I had to dig in...

What we want

A buildable electron project that includes :

  • react
  • typescript
  • hot module reloading on the react part

Getting started with the webpack-typescript template

electron-forge provides us a convenient webpack-typescript that generates a boilerplate configured with typescript and webpack support (who would have guessed ?).
Create the project using the following command :
yarn create electron-app my-new-app --template=typescript-webpack

Once the project has been created, enter it and run the project to ensure it works:
cd my-new-app
yarn start

The default app should open and display "Hello World"
The default app should open and display "Hello World"

Adding react

Now that our app opens properly, we need to add react dependencies.
In the terminal, run: yarn add react react-dom @types/react @types/react-dom

That done, replace the content of the body by the div that will contain the react app in src/index.html :

@@ -6,7 +6,6 @@

   </head>
   <body>
-    <h1>💖 Hello World!</h1>
-    <p>Welcome to your Electron application.</p>
+    <div id="root"></div>
   </body>
 </html>
Enter fullscreen mode Exit fullscreen mode

Create a file in src called App.tsx and paste the following code into it :

import * as React from 'react';

const App = () => <div>Hi from react !</div>;

export default App;
Enter fullscreen mode Exit fullscreen mode

To make sure typescript understands jsx, add "jsx": "react" in your tsconfig.json file like so:

@@ -12,7 +12,8 @@
     "resolveJsonModule": true,
     "paths": {
       "*": ["node_modules/*"]
-    }
+    },
+    "jsx": "react"
   },
   "include": [
     "src/**/*"
Enter fullscreen mode Exit fullscreen mode

Now we need to update the renderer to bind react to the div we created earlier.
First, rename it from src/renderer.ts to src/renderer.tsx then replace the content by the following:

import './index.css';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
Enter fullscreen mode Exit fullscreen mode

Now update the js entryPoint in package.json with the correct name:

@@ -52,7 +52,7 @@
               "entryPoints": [
                 {
                   "html": "./src/index.html",
-                  "js": "./src/renderer.ts",
+                  "js": "./src/renderer.tsx",
                   "name": "main_window"
                 }
               ]
Enter fullscreen mode Exit fullscreen mode

You can now run yarn start. The application should open and the react app should appear !

The application successfully running react

However, if you try to change some code in the App.tsx, the changes won't appear on your App. We need to manually install a module to hot reload changes.

Adding hot-reload

We're almost there ! Run yarn add react-hot-loader, then head over srx/App.tsx and add the following lines:

@@ -1,5 +1,6 @@
+import { hot } from 'react-hot-loader';
 import * as React from 'react';

 const App = () => <div>Hi from react!</div>;

-export default App;
\ No newline at end of file
+export default hot(module)(App);
\ No newline at end of file
Enter fullscreen mode Exit fullscreen mode

Now, we need to configure babel to use the react-hot-loader package that will enable hot reloading by creating a .babelrc file at the root of the repository and putting only one line into it :

#.babelrc
{ "plugins": ["react-hot-loader/babel"] }
Enter fullscreen mode Exit fullscreen mode

Finally, run yarn start, change the message, hit save and it should work !

CleanShot 2020-06-14 at 19.30.39.gif

Hope it helps !

Discussion

pic
Editor guide
Collapse
ipetrik profile image
IPetrik

Very helpful! I have not been able to get hot reloading to work, however. You say to use .babelrc, but in my hands the webpack-typescript template uses 'ts-loader' not 'babel-loader' by default. Even after changing the loader, however, I have not been able to get this to work.

Collapse
gist32091948 profile image
gist

that was nice walkthrough

Collapse
matrixcloud profile image
atom

Very helpful! Many thanks.

Collapse
truongluu profile image
Lưu Xuân Trường

This was a helpful walkthrough, many thanks

Collapse
manen profile image
manen

Thanks for the tutorial!

Collapse
moai196 profile image
1.96m

Excellent! Thanks

Collapse
larsolt profile image
Lars

Works great, ty