How to call a locally hosted server from Expo?
While developing a React Native application I needed my application running inside Expo on my mobile to access a mock server running on my laptop (development machine)
I’m writing this post to list out the two ways to achieve this and what I learnt about Expo’s behavior under the hood.
Index
Problem
When my application running inside the Expo app on my mobile tried to access a mock server running on localhost
on my laptop I got back a Network Error
.
To get the setup working there I figured two approaches
How Expo works?
To figure out a solution I tried to understand how Expo runs the React Native code base inside the Expo Application on our mobile. I went through Expo’s documentation How Expo works? and mapped it to the output I got for my own application
-
After executing
yarn start
I get a QR code to scan followed by‘Your app is now running at URL: exp://10.1.0.146:19000’
-
On scanning the QR code the Expo app on my mobile makes a request to
10.1.0.146:19000
. This returns a JSON which includes metadata about our application and the URL where React Native Packager Server is running. This is provided against the keybundleUrl
-
By default React Native packager runs a server on
localhost:8001
Based on the value of
bundleUrl
Expo had launched the React Native packager server on10.1.0.146:19001
-
Next the Expo app on mobile fetches the app’s Javascript from
bundleUrl
served on10.1.0.146:19001
I get a Network error
because while my application is running on my mobile it makes a request to 127.0.0.1:8000
. Presumably it either refers to the loopback address on Android where there isn’t any server running on port 8000 or the address is unidentified and hence a Network error
In order to access the mock server it has to be available either on my development machine’s IP address (where it will be accessible because my mobile and laptop are on the same network as required by Expo) or on a universally accessible URL over the internet
Solution
By using ngrok
or localtunnel
By using either of these modules we can expose a server running on localhost on the web.
Next we can use the corresponding URL to access the mock-server from our application running inside Expo
I went ahead with localtunnel
-
Installing
localtunnel
globally on my dev machineyarn global add localtunnel
-
I used
json-server
to setup and run a mock server. The following command sets up the mock server on localhost and port 8000json-server --port 8000 ./db.json --watch
-
Next to expose the mock server to the web use
localtunnel
lt --port 8000 --subdomain application-mock-server
The above command will return a URL accessible across Internet of the form
https://application-mock-server.localtunnel.me
. This URL can be plugged inside the React Native code base and will be accessible from the application running inside Expo on the mobile.
By running the mock-server on 0.0.0.0
Another approach is to run the mock server on 0.0.0.0
instead of localhost
or 127.0.0.1
.
This makes the mock server accessible on the LAN and because Expo requires the development machine and the mobile running the Expo app to be on the same network the mock server becomes accessible too.
This can be achieved with the following command when using json-server
json-server --host 0.0.0.0 --port 8000 ./db.json --watch