yonder
your site, over yonder
yonder lets you open a website running on your own computer (localhost) from your phone, your iPad, or a friend's laptop on the same network. It can also share a file or a whole folder, and let the other device send files back. One command prints a link and a QR code. Nothing needs to be installed on the other device.
Contents: Install · Quick start · Usage · Share files · How it works · Is it safe? · Known limitations · Firewalls · WSL · Documentation
Install
macOS / Linux, any distro
curl -fsSL https://raw.githubusercontent.com/dpologdvinity/yonder/master/install.sh | sh
The script checks the download's SHA-256 before installing. Set YONDER_VERSION=0.4.4 to install a specific version, or YONDER_INSTALL_DIR to choose the folder.
Homebrew (macOS and Linux)
brew install dpologdvinity/tap/yonder
Debian / Ubuntu (apt)
sudo curl -fsSLo /usr/share/keyrings/yonder.gpg https://dpologdvinity.github.io/packages/yonder.gpg
echo "deb [signed-by=/usr/share/keyrings/yonder.gpg] https://dpologdvinity.github.io/packages/apt ./" | sudo tee /etc/apt/sources.list.d/yonder.list
sudo apt update && sudo apt install yonder
Fedora / RHEL (dnf)
sudo curl -fsSLo /etc/yum.repos.d/yonder.repo https://dpologdvinity.github.io/packages/yonder.repo
sudo dnf install yonder
Arch Linux (pacman)
curl -fsSL https://dpologdvinity.github.io/packages/yonder.asc | sudo pacman-key --add -
sudo pacman-key --lsign-key 282804EB5779EA7EFFCF8308097AF7F74B2F93E5
printf '\n[yonder]\nServer = https://dpologdvinity.github.io/packages/arch/$arch\n' | sudo tee -a /etc/pacman.conf
sudo pacman -Sy yonder
Windows (Scoop)
scoop bucket add yonder https://github.com/dpologdvinity/scoop-bucket
scoop install yonder
npm / yarn / pip
npm install -g yonder-cli # or: yarn global add yonder-cli
pip install yonder-cli # or: uv tool install yonder-cli
Go
go install github.com/dpologdvinity/yonder@latest
Or download a binary, .deb, .rpm or Arch package from Releases. Every release lists the SHA-256 of each file in checksums.txt.
Quick start
- Start your site as usual, for example on port 3000.
- Run
yonder 3000. - Scan the QR code with the other device, or type the link it prints into a browser.
- Press Ctrl-C when you are done. The link stops working at once.
$ yonder 3000
yonder: sharing localhost:3000
http://192.168.1.20:13000/?yonder=…
<QR code>
Only people with this link or QR code can open it.
14:03:09 device connected 192.168.1.42
14:03:09 GET / 200 192.168.1.42
The other device must be on the same network as your computer. If it cannot connect, see Known limitations and Firewalls.
Usage
yonder <port> share the site running on localhost:<port>
yonder <path> share a file or a folder
yonder <folder> --upload also let other devices send files into the folder
yonder <target> --open share without the secret token (trusted networks only)
yonder <target> --listen N use N as the public port
yonder --version print the version
| Option | What it does |
|---|---|
--listen N |
Uses port N for other devices. By default yonder uses the shared port plus 10000 (3000 becomes 13000), or 18000 when sharing files, so the link keeps the same port across restarts. If that port is busy, yonder picks a free one. With --listen, a busy port is an error. |
--open |
Turns the secret token off. Anyone on the network can open the link. |
--upload |
Lets other devices send files into a shared folder. Folders only. |
--version, --help |
Print the version, or the usage text. |
The terminal shows one line when a device first connects, and one line per request with the time, method, path, status and visitor address.
yonder runs a small proxy in front of your dev server, so you do not need to change its configuration:
- It works with servers that only listen on
127.0.0.1or::1. - It rewrites the
HostandOriginheaders, so servers that check them (Vite, webpack, Next.js) accept the request. - Hot reload keeps working: WebSockets and server-sent events pass through.
Share files
yonder ./photos # a folder: the phone gets a list of files to tap and download
yonder notes.pdf # one file: nothing else in its folder is reachable
The link, QR code and token work the same as when sharing a port.
- Hidden files and folders (
.env,.git,.ssh, anything starting with.) are never listed or served. - Symlinks inside the shared folder are skipped, and
..cannot reach outside it. - Folder pages show the first 5000 entries, alphabetically, with folders first. A subfolder page has a
../link to go back up. - Share a dedicated folder, not your home directory.
- Add
--uploadto let the other device send files into the folder: the page gets an Upload button (on a phone it opens the photo picker or Files). Existing files are never overwritten (photo (1).jpg), folder parts of a name are dropped (../../x.txtis saved asx.txt), hidden names are refused, and one upload is capped at 4 GB. Uploads are off unless you pass the flag. With uploads on, shared pages cannot run script (see Is it safe?). - A folder named like a number is a port to yonder: use
yonder ./3000.
How it works
yonder is one program with no dependencies on the other device. It opens a server on all of your network interfaces and puts two things in front of what you share: the access gate and a request log.
phone ──▶ your computer, port 13000 ──▶ log ──▶ access gate ──┬──▶ proxy ──▶ your dev server (localhost:3000)
└──▶ file server ──▶ the shared folder
- The access gate only lets a request through if it carries the secret token: in the link on the first visit, in a cookie after that.
- The proxy forwards the request to your dev server and rewrites headers so the dev server believes the request came from
localhost. - The file server lists and serves a folder, and receives uploads, using only operating-system calls that cannot leave that folder.
ARCHITECTURE.md explains each part, the security design, and why it was built this way.
Is it safe?
The link and QR code carry a secret token. Anyone without it gets a 403 and never reaches your app. The first visit swaps the token for a cookie, so it disappears from the address bar. Every restart makes a new token, which cuts off old links. Only the one port, file or folder you name is shared.
--openturns the token off. Use it only on networks you trust.- yonder speaks plain HTTP. On open (passwordless) Wi-Fi, or on WPA2 Wi-Fi with a shared password, others on the network can capture traffic and copy the token or cookie. Avoid sharing private data there. Enterprise Wi-Fi with per-user logins and WPA3 protect each device's traffic.
- With
--upload, files that are served carry a sandbox policy, so a web page someone uploaded cannot run script on your computer's address. This also means an HTML site shared from an upload-enabled folder will not run its scripts. - Stop sharing with Ctrl-C.
To report a vulnerability, see SECURITY.md.
Known limitations
- Your app's own code may hardcode
localhost. A frontend calling an API athttp://localhost:8080fails on the phone, because therelocalhostis the phone. Use relative API URLs or your dev server's proxy. - Response bodies are not rewritten. Absolute
http://localhost:<port>links inside HTML or JS stay broken. http://localhostcounts as a secure context;http://192.168.x.xdoes not. Service workers, camera, geolocation, clipboard andcrypto.subtledo not work on the other device yet.- Guest, campus and café networks sometimes block device-to-device traffic. If the other device cannot connect, try a phone hotspot.
- yonder only shares on private networks (
10.x,172.16-31.x,192.168.x). Some networks give every computer a public address; there yonder stops with a message instead of putting your site on the internet. - Cookies do not include the port, so another web service on the same IP address receives yonder's cookie.
Firewalls
The first time yonder listens for connections, your OS may block or ask:
- Windows: allow
yonder.exein the Windows Defender Firewall prompt. - macOS: allow incoming connections when the application firewall asks.
- WSL (mirrored mode): the Hyper-V firewall blocks inbound traffic to WSL by default, so the other device times out. See the WSL section below.
If the other device cannot connect, watch yonder's output. No device connected line means the connection never reached yonder: a firewall or the network dropped it.
WSL
In WSL's default NAT mode, other devices cannot reach WSL at all; yonder prints a hint when it detects this. Either set networkingMode=mirrored under [wsl2] in %UserProfile%\.wslconfig and run wsl --shutdown, or run the Windows build, yonder.exe.
In mirrored mode, open yonder's port once in an admin PowerShell. For yonder 8000 the port is 18000:
New-NetFirewallHyperVRule -Name yonder -DisplayName yonder -Direction Inbound -VMCreatorId '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}' -Protocol TCP -LocalPorts 18000
New-NetFirewallRule -DisplayName yonder -Direction Inbound -Protocol TCP -LocalPort 18000 -Action Allow -Profile Any
Remove them later with Remove-NetFirewallHyperVRule -Name yonder and Remove-NetFirewallRule -DisplayName yonder.
Documentation
| Document | What is in it |
|---|---|
| ARCHITECTURE.md | How yonder is built: components, request flow, security design, decisions, testing and releases |
| CONTRIBUTING.md | Set up a development environment, run the checks, and send a change |
| SECURITY.md | How to report a vulnerability, and what yonder does and does not protect against |
| CHANGELOG.md | What changed in each release |
License
MIT. See LICENSE.
Metadata
Release files for yonder-cli 0.4.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| yonder_cli-0.4.4-py3-none-win_arm64.whl | Python 3 | none | Windows ARM64 | Details |
| yonder_cli-0.4.4-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| yonder_cli-0.4.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.musllinux_1_1_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64, Linux musl 1.1+ x86-64 | Details |
| yonder_cli-0.4.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64, Linux musl 1.1+ ARM64 | Details |
| yonder_cli-0.4.4-py3-none-macosx_12_0_x86_64.whl | Python 3 | none | macOS 12.0+ x86-64 | Details |
| yonder_cli-0.4.4-py3-none-macosx_12_0_arm64.whl | Python 3 | none | macOS 12.0+ ARM64 | Details |
Total release size: 23.7 MB
Release files / yonder_cli-0.4.4-py3-none-win_arm64.whl
| Download URL | yonder_cli-0.4.4-py3-none-win_arm64.whl |
|---|---|
| Size | 3.7 MB |
| Tags | Python 3 Windows ARM64 |
|
SHA-256 checksum How to use checksums |
032b49abb52ed93a5b89ccd2e681fc3469e5d4c5d7d4fbff43555f5e0f4e2d87
|
|
BLAKE2b-256 checksum How to use checksums |
a6471a930c9580f23f49949f2c49edc136b7807dbada70041c06e2e398d42d39
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / yonder_cli-0.4.4-py3-none-win_amd64.whl
| Download URL | yonder_cli-0.4.4-py3-none-win_amd64.whl |
|---|---|
| Size | 4.2 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
3c4dbcff848acbd23fa65d8c740b5ddaa05b4c381fcf92a3150b4cad703c6fe2
|
|
BLAKE2b-256 checksum How to use checksums |
447d946e57f358dfb8798667950efcf8aaa82b1f99417a148b2a18d1f8ea1ddc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / yonder_cli-0.4.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.musllinux_1_1_x86_64.whl
| Download URL | yonder_cli-0.4.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.musllinux_1_1_x86_64.whl |
|---|---|
| Size | 4.1 MB |
| Tags | Linux glibc 2.17+ x86-64 Linux musl 1.1+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
d590a07a3a3e2123b7d06a37ac538a3415c27eb2a96ca0e6ecd7750eda5bbbf2
|
|
BLAKE2b-256 checksum How to use checksums |
c2d3b82287d33d6e1e9e5b2dbf1e25b6cd257c3f0d8d81277aff3f05c1908550
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / yonder_cli-0.4.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl
| Download URL | yonder_cli-0.4.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl |
|---|---|
| Size | 3.7 MB |
| Tags | Linux glibc 2.17+ ARM64 Linux musl 1.1+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
a762e1fd3f1ef13b1028ded0543d5d4339b83cfc9732ee844d70a7f550aa1db6
|
|
BLAKE2b-256 checksum How to use checksums |
176e1a13b0aac8fd66030916e2666b3d7bf1ff2894e6f12ad992ee7d2e20a153
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / yonder_cli-0.4.4-py3-none-macosx_12_0_x86_64.whl
| Download URL | yonder_cli-0.4.4-py3-none-macosx_12_0_x86_64.whl |
|---|---|
| Size | 4.1 MB |
| Tags | Python 3 macOS 12.0+ x86-64 |
|
SHA-256 checksum How to use checksums |
0e6ef71d4c5ab0dd211f56fcfca3e4eb155163c55590a87cbf33d7833ea59ea9
|
|
BLAKE2b-256 checksum How to use checksums |
bc12dfb28fc35072d27a52020b65e84e5a18b905f4462b8b723e868979ebc46a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / yonder_cli-0.4.4-py3-none-macosx_12_0_arm64.whl
| Download URL | yonder_cli-0.4.4-py3-none-macosx_12_0_arm64.whl |
|---|---|
| Size | 3.8 MB |
| Tags | Python 3 macOS 12.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
6dd1af7f9b9fc56aea0e8604d18c00934d0693ffd3cae90c9475ce29e49533d4
|
|
BLAKE2b-256 checksum How to use checksums |
0abf4e9259ecdd7955543166e34c7f9e34139f105faedb8e0ac6bd0912cb2101
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logSecurity for yonder-cli 0.4.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 6 files in this release have been uploaded with provenance metadata.
Attestation for yonder_cli-0.4.4-py3-none-win_arm64.whl
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.