Making Desktop apps with Electron, React Native, and Expo
Tags: react, reactnative, tutorial, beginners
Published: 2019-11-26 21:23:39

**TL;DR:** [Example](https://github.com/expo/examples/tree/master/with-electron). Expo + Electron is in alpha (Nov 2019). [docs = most recent info](https://github.com/expo/expo/blob/master/docs/pages/versions/unversioned/guides/using-electron.md).

This tutorial will show you how to use React Native, Electron, Webpack, and the Expo SDK too create dope Desktop apps!

Electron is a great way to make desktop apps, and possibly the easiest. Lots of popular apps like VSCode, Figma, Zeplin, [and many others are made with it!](https://electronjs.org/apps) I like to think of it as a browser with extra native features like File System, Touch Bar, Menu Bar, Bluetooth, In-app Purchases. 

Another great framework is [Expo](http://expo.io/), you can use it to build mobile apps and websites with React. Expo for web works by using browser features with `react-native-web` whenever it can, then failing gracefully when features aren't available. 🤔 But what if Expo for web had access to all of the same features as a native app? That would probably look something like "Expo for Desktop" 😮. 

## 🚀 Tutorial

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/5zk0kcug6lhwontqh2p8.png)

TL;DR: [Here is an example repo.](https://github.com/expo/examples/tree/master/with-electron).

- Create a new Expo project with `expo init` (you can select a TypeScript project from here if you want 🥰)
  - You may need to install or update the Expo CLI with `npm i -g expo-cli`
  - This project by default can already run on iOS, Android, and web or as a PWA.
- `cd` into the project and run `yarn add -D @expo/electron-adapter`
  - This has all of the tools used to run Electron with Expo.
  - Notice that it's not built directly into Expo CLI (out-of-tree solution).
- Now run `yarn expo-electron` to bootstrap the project. Currently this does the following:
  - Install the required dependencies: `electron`, `@expo/webpack-config`, `react-native-web`, etc...
  - Create a new `electron-webpack` config file `electron-webpack.js` and 
wraps it in the method `withExpoAdapter` which ensures that everything is setup correctly.
  - Append electron generated files to the .gitignore
- Finally run `yarn expo-electron start` to start the project!
  - Everything should just open automatically.
  - You can view logs in the terminal.
  - Quit with "ctrl+c" in the terminal or by closing the browser window.
  - Make some changes to App.tsx to see the magic happen! 🧚‍♂️

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/10hvqnjgejomngt0l7bn.png)

## 🎨 [Customizing the Main Process](https://github.com/expo/expo/blob/master/docs/pages/versions/unversioned/guides/using-electron.md#customizing-the-main-process)

If you're familiar with Electron you're probably wondering ["what about the main process?"](https://electronjs.org/docs/tutorial/application-architecture#main-and-renderer-processes) (but without the hyperlink). 

**Electron has 2 processes:**
- renderer process: which is where you'll write your React application code.
- main process: Think of the "main process" as the native code in a React Native process (but still written with JavaScript). It's mostly unaware of the code running in the "renderer process", it has access to a variety of different features like creating windows.

### 📚 How it works

- By default your project uses a main-process that runs in a hidden folder (`node_modules/@expo/electron-adapter/...`).
- To customize the main process (highly recommended) you can run `yarn expo-electron customize` which will generate a folder `/electron` in your root directory.
- You'll need to restart Electron for this new folder to become the new target.
  - Everything in `electron/main` has hot-reloading enabled (!!) so that should make your life happier.
  - the `electron/webpack.config.js` can be used to modify the Webpack config for both processes (use values passed to the method to detect which is which).

## 📂 File Structure

|- `electron/`
|-- `webpack.config.js`
|-- `main/` All main process code goes in here
|--- `index.js` Entry point for your main process
|- `dist/` Electron will generate files here, do not edit it directly.
|- `electron-webpack.js` Config file for the package `electron-webpack` which is required to run your project.
|- `App.tsx` || `App.js` The entry point of your renderer process, unless you change it in the `package.json`
|- `src/` Not required, but you can put all of your renderer process code in here
|- `assets/` All static assets, images, fonts, icons, SVGs, videos, etc...

## ⚙️ Building your project

At the time of writing this (Nov 2019) expo/electron-adapter doesn't provide any special building utils. But I've put together a guide for building a project with existing Electron packages: [Expo Docs: Building Electron apps](https://github.com/expo/expo/blob/master/docs/pages/versions/unversioned/guides/using-electron.md#building-your-project)

## 🤭 Why Electron

"Why not just use a fully native solution like OSX and react-native-windows?" the reason is ... why not both! 🥳 

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/w3qhkirtqmrhp2zzgiix.gif)

In the future want to deliver the optimal experience for every platform, but we also really appreciate the ability to choose your stack. So for now you can use Electron, but in the future there will probably be even better native workflows provided by Expo.

## 🧸 [Behavior](https://github.com/expo/expo/blob/master/docs/pages/versions/unversioned/guides/using-electron.md#-behavior)

- Webpack now resolves files with `.electron.js` & `.web.js` extensions in that order. If you want to use electron features then put them in a file like `foo.electron.js.`
- Every universal package you have installed will be transpiled automatically, this includes packages that start with the name: expo, @expo, @unimodules, @react-navigation, react-navigation, react-native. You can add more by appending them to the array for key `expo.web.build.babel.include` in your `app.json` (this feature is experimental and subject to change).
- I wrote the docs that I just blatantly lifted this section from :]

## 👋 Thanks so much

That's all for now, to stay updated on new features feel free to follow me on Twitter, Github, Dev..ehh...