Network Access
R code that fetches from the internet needs a proxy, and webRios runs one on your device. The setting is in Settings > R Session > Network; the mechanism and its limits are in How network access works.
Why there is a proxy at all
R compiled to WebAssembly has no sockets, so curl can’t open a connection. The webR project turns those connections into WebSockets tunnelled through a SOCKS proxy. Somebody has to run that proxy; webRios runs one inside the app, so requests go straight from your device to the site.
Choosing a route




| Setting | What happens |
|---|---|
| On-Device Only (default) | Requests go through the proxy inside the app. If it can’t start, curl requests are blocked and you are told. They are never rerouted. |
| On-Device, Public Fallback | The same, except that if the proxy can’t start, requests go through a public proxy hosted at r-universe.dev, and you are told. |
| Public Proxy | Every request goes through the public proxy. The on-device one is not started. |
This Session shows the route the running session actually uses. A change applies when R restarts, and Restart R to Apply appears until it does.
A sample run
install.packages("curl")
library(curl)
r <- curl_fetch_memory("https://example.com")
r$status_code
#> [1] 200




Telling which route R is using
Settings shows it, and so does R. The proxy address is in ALL_PROXY:
sub(".*@", "", Sys.getenv("ALL_PROXY"))
#> [1] "127.0.0.1:52341"Strip everything up to the @ first: the on-device address carries a per-launch credential that has no business on screen or in a saved script.
| What you see | Route |
|---|---|
127.0.0.1:<port> |
The on-device proxy |
ws.r-universe.dev:443 |
The public proxy |
on-device-proxy-unavailable://… |
Blocked. curl requests fail immediately |
ALL_PROXY is set when curl first loads, so it reads empty until a session uses it.
Using the public proxy




The public proxy is the one the WebAssembly build of curl uses on its own, outside webRios: a shared service with public credentials, not run by us. It can see your IP address and which sites you connect to, but not the contents of https requests, which R encrypts with the site itself. R also contacts r-universe.dev to find the proxy when the session starts, before any request of yours.
A session on the public proxy reports the r-universe address:




When the on-device proxy can’t start
You are told once per launch, and the alert offers to allow the public proxy instead.




Until you do, curl requests fail immediately, naming the reason:




This affects httr2, and readr, vroom or xml2 reading from a URL, since they switch to curl once it is installed. Package installs and download.file() keep working; see below.
If you allow the fallback, R restarts and the session tells you it is on the public proxy:




After the app has been in the background
iOS can close a suspended app’s network listeners, the on-device proxy among them. When you return, webRios restarts the proxy if it has gone and points R at it, usually on a new port, so ALL_PROXY shows a new address with the same credential. An already-loaded curl picks up the change; you do nothing.
If the proxy can’t start again, curl requests are blocked for the rest of the session, whatever the setting, and the Console suggests restarting R. They never move to the public proxy unless you choose it. Through the on-device proxy, a host that refuses, doesn’t exist or can’t be reached fails at once with a reason, not after a 30-second timeout.
What this setting does not cover
download.file(), url(), read.csv(url) and package installs take a route no proxy setting touches: straight from your device to the site, in every mode, even with curl blocked. They obey the cross-origin rules a web page does; see Network access from R.
The setting is a default rather than a sandbox. R code that sets its own proxy, for example with httr2::req_proxy(), overrides it.
For what each route means for your data, see the Privacy Policy.