DEV Community

Cover image for How to create an electron-forge project with React, Typescript and HMR
Raphaël Badia
Raphaël Badia

Posted on • Updated on

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

introduction

This post has been transferred to my blog. You can read the latest version here:
How to create an electron-forge project with React, Typescript and HMR


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 !

Top comments (12)

Collapse
 
matheusgrieger profile image
Matheus Grieger

Thank you so much, this is very helpful!
However, do you have any idea how to use images and static assets (like fonts) in the app? Trying to import them just doesn't work, and I can't seem to get copy-webpack-plugin to work either.

Collapse
 
thyenigmatic profile image
Kapil Bastola

Thanks for the setup walkthrough. As I followed your steps, I encountered error when adding line:
import App from './App';

and the error was :
Unable to resolve path to module './App' .(import/no-unresolved).

After some digging and googling I found the solution here: stackoverflow.com/questions/598258...

adding :


'settings': {
'import/resolver': {
'typescript': {},
},
},


to .eslintrc.json worked.

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
 
manen profile image
manen

Thanks for the tutorial!

Collapse
 
kabrau profile image
Marcelo Cabral Ghilardi

Tks !!!!

Collapse
 
focuscookie profile image
Stephan Lüddemann

Thanks for the walkthrough.

At the step with the entryPoints, it is not in the package.json - it is in the forge.config.ts

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

This was a helpful walkthrough, many thanks

Collapse
 
matrixcloud profile image
atom

Very helpful! Many thanks.

Collapse
 
shadab19it profile image
Shadab Alam

Thank you working fine