TL;DR: Example. Expo + Electron is in alpha (Nov 2019). docs = most recent info.
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! 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, 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
TL;DR: Here is an example repo..
- 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.
- You may need to install or update the Expo CLI with
-
cd
into the project and runyarn 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 fileelectron-webpack.js
and wraps it in the methodwithExpoAdapter
which ensures that everything is setup correctly. - Append electron generated files to the .gitignore
- Install the required dependencies:
- 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! ๐งโโ๏ธ
๐จ Customizing the Main Process
If you're familiar with Electron you're probably wondering "what about the main process?" (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).
- Everything in
๐ 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
๐คญ Why Electron
"Why not just use a fully native solution like OSX and react-native-windows?" the reason is ... why not both! ๐ฅณ
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
- 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 likefoo.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 yourapp.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...
Top comments (15)
Thanks for writing this guide!
I tried creating a demo app with it and it works in development mode.
The only problem is that the build doesn't seem to work.
I'm getting this error when compiling in mac:
I used the following command to compile:
yarn electron-webpack && yarn electron-builder --dir -c.compression=store -c.mac.identity=null
There were no errors in the compilation process. My
babel.config.js
looks like:any ideas why this is? does
babel-preset-expo
support global module imports?again, thank you for this. I'll continue trying to figure out what's wrong.
Hi, there.
I'm getting a similar error. I've been trying to fix it by changing the syntax for that line from 'import from ...' to 'require('....')'.
It "worked" in the way that the error moved to the next "import" statement.
Is ES6 not working on the build?
Tried using other babel presets (babel/env, babel-react, etc...). With these ones, not even the building finishes.
Can't find any solution
Any answer on the subject, I have the same problem, a build example would be welcome.
@Wern, I have same issue. Did you find any solutions?
Any luck to create build for electron?
Wow that looks awesome! When you use Expo to make Electron apps you also get an iOS and Android app as well though.
Great post - I featured this on React Native Now newsletter #56
Awesome, thanks so much!
Great stuff. Thanks for sharing Evan. I've done a lot of React, but still haven't touched any of the native stuff, including Expo. Maybe I should start. ๐
Yes it technically can, but simply isn't supported at all at the moment.
really helpful post
i may need to figure out how can i resize the window and make use of electron
Any way to run Expo app without having to download your JS bundle every time?
Yes,are you referring to during production or dev?
Hello, I have problems with the implementation of Redux with this package...
Do you have any idea?
Thank you
React Native desktop is available on Mac and Windows, but these aren't the only OS that exist on this planet. Some people use Linux