# Getting Started with Electron, Typescript, React and Webpack


> If you are a web developer and you want to build a native app that solves a daily workflow problem or if you have a web app built completely and want to give users more of your app with native capabilities . Then there is an easy way to do that with electronJs.This tutorial will help you build a web application that works as a native app.

Let’s use a basic electron starter project and then enhance it to an enterprise ready application

# **Initialise and an empty electron project**

We will first initialise an empty electron project that will look similar to an [electron first app](https://electronjs.org/docs/tutorial/first-app) or [electron quick starter repository](https://github.com/electron/electron-quick-start)

Electron has two processes one is **main process**, *electron itself* and other one is **renderer process**, where our *web application runs*.

Now let's install the dependencies

```
npm init -y
npm install --save-dev electron
```

Electron (main) entry point

```
// src/electron.js
const { app, BrowserWindow } = require('electron');function createWindow () {
  // Create the browser window.
  let win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  });  // and load the index.html of the app.
  win.loadFile('index.html');
}app.on('ready', createWindow);
```

Electron (render) entry point

```
<!-- // src/index.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World!</title>
  </head>
  <body>
    <div id="app">
      <h1>Hello World!</h1>
    </div>
  </body>
</html>
```

We can run the app with `npx electron src/electron.js`. We’ll add this in our `package.json` as a script.

```
// package.json
"scripts": {
  "start": "electron src/electron.js"
}
```

## **Adding TypeScript**

The boilerplate JavaScript is also valid TypeScript, so let’s rename `src/electron.js` to `electron.ts`. We just need to install the TypeScript compiler and configure it.

Install dependencies

```
npm install --save-dev typescript
```

TypeScript configuration

```
touch tsconfig.json
```

Update npm scripts

```
"scripts": {
  "build": "tsc src/electron.ts"
}
```

## **Adding Webpack**

Next we’ll set up [Webpack](https://webpack.js.org/) to optimize our application. Webpack configuration consists of an array of **entry points**. Webpack processes each entry point by passing the file (and its dependencies) through a **loader**. Loaders are selected via **rules**, often with a loader per file extension. Finally, Webpack dumps the output to a specified location.

We’ll create a single entry point for our electron main process, add a loader for all `*.ts` files to pass through the TypeScript compiler, and tell Webpack to dump the output alongside the source files.

Install dependencies

```
npm install --save-dev webpack webpack-cli ts-loader
```

Webpack configuration

```
// webpack.config.js
module.exports = [
  {
    mode: 'development',
    entry: './src/electron.ts',
    target: 'electron-main',
    module: {
      rules: [{
        test: /\.ts$/,
        include: /src/,
        use: [{ loader: 'ts-loader' }]
      }]
    },
    output: {
      path: __dirname + '/src',
      filename: 'electron.js'
    }
  }
];
```

Here’s a breakdown of each piece of the configuration:

- `mode: develop` Development build (as opposed to production).
- `entry: './src/electron.ts` Location of the entry point
- `target: 'electron-main'` Specifies which environment to target; Webpack knows about the electron main process specifically.
- `test: /\.ts$/` Specifies that this rule should match all files that end with the `.ts` extension.
- `include: /src/` Specifies that all files within `src` should be considered for matching this rule.
- `use: [{ loader: 'ts-loader' }]` Specifies which loader(s) to use when this rule matches.
- `path: __dirname + '/src'` Directory where all output files will be placed.
- `filename: 'electron.js'` Primary output bundle filename.

Update npm scripts

```
// package.json
"scripts": {
  "build": "webpack --config ./webpack.config.js",
  "start": "npm run build && electron ./src/electron.js"
}
```

## **Adding React**

The React render process does not need to know it’s being used within an Electron context, so setting up React is similar to setting up a vanilla React project.

Install dependencies

```
npm install --save-dev react react-dom @types/react @types/react-dom
```

React entry point

```
// src/react.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';const Index = () => {
    return <div>Hello React!</div>;
};ReactDOM.render(<Index />, document.getElementById('app'));
```

TypeScript configuration

Our render entry point is `.tsx` and not `.ts`. The TypeScript compiler has built-in support for TSX (The TypeScript equivalent of JSX), but we need to tell TypeScript how to handle our TSX resources. Not surprisingly, we’re using the React TSX variety.

```
// tsconfig.json
{
  "compilerOptions": {
    "jsx": "react"
  }
}
```

Next, we’ll create a new entry point in Webpack’s configuration. Webpack will process our entry point (and its dependencies) and load the result into our `index.html` via the html-webpack-plugin.

Install dependencies

```
npm install --save-dev html-webpack-plugin
```

Webpack configuration

```
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = [
  ...
  {
    mode: 'development',
    entry: './src/react.tsx',
    target: 'electron-renderer',
    devtool: 'source-map',
    module: { rules: [{
      test: /\.ts(x?)$/,
      include: /src/,
      use: [{ loader: 'ts-loader' }]
    }] },
    output: {
      path: __dirname + '/dist',
      filename: 'react.js'
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: './src/index.html'
      })
    ]
  }
];
```

This configuration is similar to that of our main process, but there are some new items:

- `target: 'electron-renderer'` Specifies which environment to target; Webpack knows about the electron renderer process specifically.
- `plugins ...` Specifies any plugins used during the build process. Plugins differ from loaders in that plugins operate at the **bundle** level and can more deeply integrate with the build process via hooks. Loaders operate at the **file** level. The `HtmlWebpackPlugin` will automagically add a reference to the output bundle in the specified `template` file.

Since the output path for our renderer files is no longer the `src` directory, we’ve instructed Webpack to put our resources in a new `dist` directory. Let’s do the same for the main process’ configuration.

```
// webpack.config.js
...
  output: {
    path: __dirname + '/dist',
    filename: 'electron.js'
  }
```

With our output files now inside the `dist` directory, we need to update our npm scripts to match.

```
"scripts": {
  ...
  "start": "npm run build && electron ./dist/electron.js"
}
```

# **Conclusion**

Now we can see how Electron turns out to be suited for most of the web frameworks and Webpack is well suited for packaging multiple things at once.

