How can i connect my phone to expo when using WSL2 to run it

To add to Simons answer, here is what I had to do to get it running.

Forward the requests coming to Windows to the WSL2 instance.

In your WSL2, run ip addr (Ubuntu). This will give you your IP address. Look for eth0, probably something like "inet 172.22.182.52". (note that if you are running multiple Expos on your machine then you may need to do this for more ports)

Then, in a Windows terminal (as administrator), run:

netsh interface portproxy add v4tov4 listenport=19000 connectport=19000 connectaddress=172.22.185.52
netsh interface portproxy add v4tov4 listenport=19001 connectport=19001 connectaddress=172.22.185.52
netsh interface portproxy add v4tov4 listenport=19002 connectport=19002 connectaddress=172.22.185.52

Allow requests through Windows firewall

Windows firewall blocks stuff. Good. Now open up the ports expo needs. (note that if you are running multiple Expos on your machine then you may need to do this for more ports)

Inside Windows terminal (as administrator):

iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort 19000 -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort 19001 -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort 19002 -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort 19000 -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort 19001 -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort 19002 -Action Allow -Protocol TCP";

WSL2 IP changes on restart

I haven't tried these yet, but here are some scripts that automatically update the above stuff for you on restart.

  • https://gist.github.com/xmeng1/aae4b223e9ccc089911ee764928f5486
  • https://www.brianketelsen.com/blog/ssh-to-wsl2/

(Bonus) Update QR code that comes from Expo

You need to have a custom environment variable that specifies a different host for the QR code URL. Easiest is to prepend the variable to the command that you run. Preferably your project would have a file set up where you can put these variables.

In a terminal in Windows, run: ipconfig /all. Somewhere there you will have the IP address to your Windows machine. Probably under Wireless adapter or Ethernet adapter.

In your project (from WSL2): REACT_NATIVE_PACKAGER_HOSTNAME=<IP address to your Windows machine> yarn expo:start (or whatever your command is).


I was having this issue and this is the main thread about the topic so I thought I'd add a solution that worked for me.

To reiterate, this is running Expo SDK 36 and WSL2 (Ubuntu 18.04 LTS, Win 10 build 19559.1000).

expo start would run (in WSL2), and the QR code would pop up. Scanning the code with my phone would result in an error.

The solution I found was to go to the Metro Bundler window that opens up. Under "Connection", three options are available: Tunnel, LAN, and Local. expo start defaults to LAN. This is where the error is seeming to occur.

The solution was to switch from LAN to Tunnel. This produces a new QR code which allows the Expo phone app to correctly identify and connect to the Expo project.

expo start --tunnel

I understand that the original post didn't want to use the tunneling option, but for those who can, this works.

Hope this helps!


Here's the full steps I found worked for LAN development between my mobile and expo running in WSL2 (Ubuntu 20 on Windows 10 20H2):

1. One time at the start: open Expo ports inbound in Windows Firewall

Windows firewall should be on, and it should block inbound attempts by default.
The following will open the Expo ports 19000–19006, inbound, but only on a network that you have configured as "private" (that's the -Profile Private part):
(powershell as Admin)

New-NetFireWallRule -Profile Private -DisplayName 'Expo ports for LAN development' `
    -Direction Inbound -LocalPort 19000-19006 -Action Allow -Protocol TCP

(You can check it after with Get-NetFirewallRule |Where-Object {$_.DisplayName -Match "Expo.*"})

2. Point portproxy to WSL; Re-run "Each time WSL has a new IP address"

(I'm not sure yet how often the WSL IP address changes, but I suspect only a reboot would)

I saw stuff on the web, including other answers here, saying portproxy to connectaddress=127.0.0.1 but it did not work for me (WSL2, Windows 10 20H2).
I can't say why others found it worked, I can only say that repeated testing confirmed for me that 127.0.0.1 did not work, but the WSL IP address did work.

So here's a reusable command to auto set the connectaddress to the right WSL address:
(powershell — just for the easy inline Trim() — as Admin)

netsh interface portproxy add v4tov4 listenport=19000 listenaddress=0.0.0.0 `
    connectport=19000 connectaddress=$($(wsl hostname -I).Trim());

netsh interface portproxy add v4tov4 listenport=19001 listenaddress=0.0.0.0 `
    connectport=19001 connectaddress=$($(wsl hostname -I).Trim());

3. Point Metro to your dev machine LAN IP Address; Re-run inside WSL "Each time dev host has a new IP address"

This is the one that probably changes most often. Your laptop local network IP certainly changes when you change networks (e.g. home/office) — and can change at other times too.

Fortunately it's also pastable / aliasable:
WSL2 shell

export REACT_NATIVE_PACKAGER_HOSTNAME=$(netsh.exe interface ip show address "Wi-Fi" | grep 'IP Address' | sed -r 's/^.*IP Address:\W*//')

echo Meteor will use dev machine IP address: $REACT_NATIVE_PACKAGER_HOSTNAME

(If your dev box doesn't change LAN often, you might get away with setting REACT_NATIVE_PACKAGER_HOSTNAME in your .bashrc / .zshrc)


I "wish I didn't have to re-run things and it could all be automated",
but that same laziness makes me happy to at least have commands 2 and 3 able to simple "rerun" and consistently get Expo LAN mode working for my WSL2-hosted Expo dev mode.