Building macOS Applications with React Native for macOS
Responses (0)
Hey there! 👋 Want to get 5 free lessons for our Building React Native Apps for Mac course?
Did you know Slack's and Discord's desktop clients are built with the Electron framework? Using Electron allows developers to bring their web applications to desktop faster without having to rewrite them completely as standalone, native clients that run on multiple operating systems. However, a major downside of building desktop applications with Electron is its high memory consumption and size because it packages the final build with a copy of Chromium, an open-source alternative of the Chrome browser, and Node.js to run an application written with HTML, CSS and JavaScript. At a high level, an Electron application behaves like a Chrome browser and loads and renders an HTML document inside of a window (BrowserWindow
).
To avoid the extra overhead of Chromium and Node.js and make the UI appear consistent with a platform's trademark design by rendering it with native APIs and components, consider using a different framework like React Native for Windows and macOS. Launched in 2019 and forked from Facebook's React Native project, React Native for Windows and macOS is an open source project maintained by Microsoft and allows developers to create Windows and macOS applications with a single React Native codebase. To interact with native APIs, the macOS port uses Objective-C or Swift while the Windows port uses C# or C++/WinRT. React Native for Windows and macOS comes with React components that are transformed into native components of each platform at runtime and can readily be imported from the react-native
library.
Composing an interface with native components instead of wrapping an entire web application inside of an application shell results in faster and smaller desktop applications. With all the tooling and CLI utilities provided by React Native for Windows and macOS, a developer can easily get started and deliver an application with a solid desktop experience.
Below, I'm going to...
Discuss the advantages/disadvantages of using React Native for Windows and macOS.
Bootstrap and build a simple macOS application with React Native for Windows and macOS.
Compare the memory consumption and sizes of the applications generated by Electron and React Native for macOS.
Evaluating the Pros and Cons of React Native for Windows and macOS.#
Like any other piece of technology and library/framework, you need to decide whether React Native for Windows and macOS is appropriate for your particular use case by weighing its upsides against its downsides. Being aware of its strengths and weaknesses ensures our application best meets expectations.
Here are several advantages for using React Native for Windows and macOS:
Barrier of Entry / Onboarding - For small development teams with fewer resources, developers proficient with JavaScript and React can contribute to an existing project or create a new desktop application. Additionally, the job market has many more candidates who specialize in web technologies than native technologies.
Hot Reloading - Unlike native development that requires you to manually rebuild the application to view changes anytime you edit your code, React Native automatically updates the application with those changes while also preserving state. Having this quick feedback loop lets you rapidly iterate on the application.
Code Reusability - React encourages components and hooks to be reusable. If you have already built a mobile application with React Native, then you can reuse its components and hooks to bring the same mobile experience to desktop, and vice-versa, with minor modifications.
Performance - Compared to other cross-platform alternatives, applications built with React Native for Windows and MacOS perform better due to being more lightweight and leveraging native components. With its large backing, React Native continues to improve on all fronts, especially on performance. There are future plans to rearchitect React Native to no longer serialize/deserialize data during communication between JavaScript and native (and vice-versa) code by replacing the bridge with JSI.
Community and Ecosystem - React Native's community and ecosystem have grown tremendously over the past several years. With so many quality libraries and third-party integrations available for React Native, building complex UIs becomes less time-consuming.
Here are several disadvantages for using React Native for Windows and macOS:
Maturity - Although React Native itself is mature and used to build production-grade applications by many reputable companies and startups, the macOS port lacks as much documentation and support for native features as React Native. Being released as recently as 2020, it is highly likely that you will encounter a decent number of bugs or dive into native code (and internals) to implement some functionality. Nevertheless, it won't take long for the project to reach a suitable level of maturity because of Microsoft's backing.
Native Limitations - Similar to other environments, there will be problems specific to native environments that simply cannot be solved unless you have native knowledge.
Performance - No matter which JavaScript framework you choose, you cannot build an application that reproduces the exact same performance as seen in native applications.
Remember. By spending a bit of time upfront to pick the best framework for your project, it will save you much more time during development.
First Steps with React Native for Windows and macOS#
To get started with React Native for Windows and macOS, initialize a standard React Native project via the react-native init
command. Specify the template version to match the latest minor version of React Native for Windows and macOS.
Note: projectName
cannot contain any spaces or hyphens; it must be alphanumeric and camelcased. Otherwise, the react-native
CLI tool prints the following error message: error "<projectName>" is not a valid name for a project. Please use a valid identifier name (alphanumeric).
During the initialization of the project, you may be prompted with the following question:
CocoaPods (https://cocoapods.org/) is not installed. CocoaPods is necessary for the iOS project to run correctly. Do you want to install it?
CocoaPods is a dependency manager for languages (Swift, Objective-C, etc.) that execute inside the Objective-C runtime. Select "Yes, with Homebrew" if you already have Homebrew installed on your machine. Otherwise, select "Yes, with gem (may require sudo)."
Note: Make sure Homebrew and packages are up-to-date! Otherwise, you may eventually encounter the following error: dyld: Library not loaded
.
Inside of the new project, install the macOS-specific packages via the react-native-macos-init
command:
Note: Install Windows-specific packages via the react-native-windows-init
command.
This creates a macos
directory at the root of the project directory, and it contains the macOS project.
Run the macOS application (with hot-reloading) via the react-native run-macos
command:
Note: Run the Windows application via the react-native run-windows
command.
This may take some time as it needs to compile all the native code necessary to run the application.

In the above screenshot, you may notice an additional terminal window that opens when running the application. This window contains Metro, the React packager. This window must be kept open for the application to work properly during development.
If you run into the following error:
Then inside of the macos/<projectname>-macOS/ViewController.m
file, correct the casing of moduleName
, which must follow the same casing as your project's name (camelcased), not lowercased.
Anytime you modify the App.js
file, watch those changes be automatically reflected in the application!
(App.js
)
To build a release (a .app
file) for distribution, add the following script to package.json
:
(package.json
)
Note: projectname
is projectName
, but lowercased.
Here, the build configuration of xcodebuild
is set to "Release." Also, the build takes a while to complete. Once completed, the path to the release is printed within the logs.

When you double-click on the release, the application opens. Feel free send a copy of the application to other team members to test on their macOS machines.

Electron vs. React Native for Windows and macOS#
As opposed to Electron applications, React Native for Windows and macOS applications consume less memory and spawn less processes. If you run barebone applications built with these frameworks on the same machine and compared them side-by-side, then you will notice these differences.
Here, we will compare three applications:
An Electron application based on the instructions of the "Quick Start" page of the Electron Documentation. It displays a simple, static HTML document inside of the shell.
An Electron application based on Electron Forge's React, TypeScript and Webpack template. It displays an HTML document that has the
<App />
component rendered within a<div id="root" />
container element.A React Native for Windows and macOS application bootstrapped with
react-native-macos-init
.
When we run these three applications on the same macOS machine and open Activity Monitor, even though the Electron applications display static content, they each spawn four processes (one main and three helper processes based on Chromium's multi-process architecture). Altogether, these processes consume more than twice the amount of memory consumed by the single React Native for Windows and macOS application's process.


Similarly, if you run the top
command, which displays CPU and memory utilization information, inside of a terminal, you will also make the same observation.

Space-wise, the application built with React Native for Mac takes up significantly less space on your machine than the applications built with Electron.

Download this repository with the source code of these applications to replicate these findings.
Next Steps#
Try building your next desktop application with React Native for Windows and macOS!