React Native Expo on WSL2

Kendall
Weavik
Published in
4 min readSep 3, 2021

A tale of slaying the seemingly insurmountable beast that is React Native Expo on WSL2!

During the past year, I have been blessed to be able to make the transition to working from home quite smoothly.

Although the occasional speedbump arises, the experience has been rather enjoyable (for the most part). That being said, there are definitely some quirks that have arisen; namely, developing on a Windows machine…

While this may have once been the ultimate no-no, the advent of WSL (and WSL2) have redefined what ‘developing on Windows’ looks like. However, the ‘best of both worlds’ is so rarely just that — keep reading to see what I mean!

Expo Connection Issues

As a growing React Native developer, I have come to appreciate the role Expo can play in managing a project through its infancy.

However, I soon ran headfirst into a slight configuration issue…connecting the Expo “testing” app to the bundler server. Due to the completely unknown (to me) architecture of WSL2, the Expo app simply could not connect to the development server. I experimented with using the “tunnel” option (exposes Expo bundler over an ngrok tunnel), but soon tired of the long wait times in between changes.

This frustration convinced me to dust off my Google-fu and track down the answer to the configuration riddle. One exhausting journey later, and after many inevitably false sidequests, I stumbled upon the answer.

After a bit more wrangling I was able to create a relatively smooth workflow that I hope can make your life easier as well!

TL:DR; Final solution can be found at the GitHub Gist

Understanding the Issue

The underlying issue was, as even the briefest Google search revealed, with the ports involved. Traditionally, the Expo server exposes port 8081 to serve the bundled JS. However, since these ports were being used within the WSL2 environment, the Expo app could not connect (since WSL2 does not operate on same LAN/WiFi network).

NOTE: Until Expo 49, the Expo server exposes port 19000 to serve the bundled JS, and uses port 19002 as a development UI. From Expo 48 on, port 8081 is used instead.

The obvious solution was to forward the easily accessible Windows ports to their matching ports in WSL2…until that didn’t work.

More research indicated that the Windows Firewall would need to be configured as well, to allow accessing those ports at all. At this point, the end was in sight, until I made a startling wise yet foolish decision — automation.

Running the same set of commands seemed far too onerous, so I looked at creating a Powershell script. This was honestly the most painful part of the experience, but I “powered” through it and eventually, finally, delivered the death blow.

As I licked my wounds and smoothed my pride, I gazed upon the final solution with a single thought: “I̶t̶ ̶i̶s̶ ̶b̶e̶a̶u̶t̶i̶f̶u̶l̶” “It is finished.”

Sharing the Solution

This would never have been possible without a few brave souls who have gone before: Stack Overflow — WSL2 via LAN and GitHub — WSL2 Bridge Mode; may they rest in peace!

  • Configure Windows Firewall to allow Expo ports
  • Proxy Expo ports from Windows to WSL2
  • Update Expo address for scanning QR

The final solution is available as a GitHub Gist (embedded below), which can be implemented as a PowerShell script. To simplify usage, create a shortcut with a target of powershell.exe -ExecutionPolicy Bypass -f <file_path> and assign it administrator privileges. Combined with the modified Expo start command, this results in a simple workflow when resuming development.

For Expo < 39, avoid proxying port 19002 with the catch-all Windows IP, as this will prevent accessing the development tools in the browser!

Finally, add another NPM script (which will be run within WSL2) to update the Expo start command. In order to properly update the Expo QR code (scanned by Expo app), the React Native packager URL must be updated with the IP of the Windows host (not the default WSL2 IP!).

"start:wsl": "REACT_NATIVE_PACKAGER_HOSTNAME=$(netsh.exe interface ip show address 'Ethernet' | grep 'IP Address' | sed -r 's/^.*IP Address:\\W*//') expo start",

Combined, these two approaches should enable developing with Expo from within WSL2 in two easy steps: run the PowerShell script (shortcut) and finish up with npm run start:wsl!

If using Wi-Fi instead of Ethernet connection, change out “Ethernet” above with “Wi-Fi”!

Summary

Additional steps could include running this PowerShell script automatically upon login (using Task Scheduler); however, I prefer only running when necessary…

Developing React Native apps with Expo on WSL2 is definitely tricky (not impossible!), but definitely worth the tradeoffs if you want a Windows experience!

Best wishes, and happy beast-slaying!

--

--