A VM started from the SDK can install packages with apk, but it cannot reach the rest of the internet on its own: a web page cannot open TCP connections. The internet gateway does that for it. It is a small server you run on your own machine or VPS, the VM sends its connections to it over a WebSocket and it proxies it into the TCP connection.
It is distributed as binary and can be installed by a simple curl download:
| System | Download |
|---|---|
| Linux, x86-64 | arm64js-gateway-linux-x86_64 |
| Linux, arm64 | arm64js-gateway-linux-arm64 |
| macOS, Apple silicon | arm64js-gateway-macos-arm64 |
Checksums are in SHA256SUMS.
curl -fLo arm64js-gateway https://cdn.arm64js.com/gateway/latest/arm64js-gateway-linux-x86_64 # Linux, x86-64
curl -fLo arm64js-gateway https://cdn.arm64js.com/gateway/latest/arm64js-gateway-linux-arm64 # Linux, arm64
curl -fLo arm64js-gateway https://cdn.arm64js.com/gateway/latest/arm64js-gateway-macos-arm64 # macOS
On macOS download with curl rather than the browser as macOS blocks downloaded software not signed by them. If you already downloaded it that way you can unblock with xattr -d com.apple.quarantine arm64js-gateway.
To start:
chmod +x arm64js-gateway
./arm64js-gateway --ws 127.0.0.1:4434
When creating your VM specify that it has access to the gateway:
const vm = await Arm64JS.boot('alpine', { gateway: { url: 'ws://127.0.0.1:4434' } });
await vm.exec('wget -qO- https://example.com');
By default the gateway relays every connection including local, so pretty much anything you can access from that machine becomes available for the VM. To limit what it can proxy use the options below.
| Option | What it does |
|---|---|
--allow-host registry.npmjs.org |
Relay only TCP connections to this address. Accepts wildcard domains (such as *.npmjs.org) and IP addresses, can be specified multiple times. |
--allow-origin https://app.example.com |
Serve only web pages from this origin. Can be set multiple times to include multiple origins. |
--token <secret> |
Serve only clients that send the same token: { gateway: { url, token: '<secret>' } }. |
For example, a gateway that lets the VM use only npm for a specific page:
./arm64js-gateway --ws 127.0.0.1:4434 \
--allow-host registry.npmjs.org \
--allow-origin https://app.example.com
Good to know:
https://cdn.arm64js.com, not your page. So it's better to use --token in that case.https (or from localhost, which is not asked). A gateway on a public address never triggers the prompt.wss://: browsers block plain ws:// from an https page to anything other than the local machine. Put it behind a proxy that does TLS, for example Caddy: reverse_proxy 127.0.0.1:4434.apk packages come from apk.arm64js.com and only use the gateway when that download fails.