Private remote shells for machines you own—without opening inbound ports or operating a VPN. Pair once with a short code, then reconnect by name from a terminal.
zuko runs a real PTY over Iroh, which provides dial-by-key reachability, NAT traversal, relay fallback, and end-to-end encryption. The supported core is deliberately small: a Linux/macOS host, the Rust CLI, explicit device authorization, and short reconnects.
Install the CLI on a Linux or macOS host:
curl --proto '=https' --tlsv1.2 -LsSf https://zuko.adonm.dev/install.sh | sh
# Relaunch your shell here if the installer asks.
zuko installPair from another machine with the CLI installed:
# host: prints a one-time two-word code
zuko share
# client: claims, saves, and connects
zuko iridescent-hilton
# later
zuko homeThe installer bootstraps and activates mise when needed, then installs Zuko as a mise-managed global tool. Relaunch your shell first if it asks. See Getting started for mise, version selection, service logs, and first connection. Windows hosts can use the documented WSL2 setup, with lifecycle limitations.
The graphical Linux client is available from FlatPark's signed Flatpak remote:
flatpak --user remote-add --if-not-exists flatpark \
https://dl.flatpark.org/flatpark.flatpakrepo
flatpak --user remote-add --if-not-exists flathub \
https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak --user install flatpark dev.adonm.zukoSee the FlatPark package page and Linux delivery notes for sandbox permissions and keyring requirements. FlatPark is an independent community repository and is not affiliated with Flathub.
| Tier | Surface | Commitment |
|---|---|---|
| Core | Linux/macOS host and Rust CLI | Primary supported workflow |
| Beta | Flutter Android, iOS/iPadOS, macOS, and Linux clients | Shared graphical client with store, preview, or community package delivery paths |
| Labs | Flutter web/Windows clients and Linux zuko app |
Deployed or buildable, with channel-specific gaps documented below |
See Clients for the exact capabilities and delivery channel of each target, and the client build guide for fresh Android, Apple, web, Linux, and Windows builds.
Fully signed public-store delivery across the graphical targets is still being worked on. For testing, the checksummed artifacts on the latest GitHub Release are the preferred source; the Clients page documents platform-specific gaps and the separate internal TestFlight channel.
zuko is not a durable session manager, full remote desktop, or centralized
fleet-access system. Use tmux, zellij, or screen for work that must survive
disconnects and host restarts.
zuko <name> # connect
zuko # TTY picker / non-TTY list
zuko share # authorise a new client
zuko claim <code> --as x # explicit claim form
zuko doctor # check service, ticket, state, and network
# inside a connected host shell:
zuko tunnel 8000 # client loopback → host 127.0.0.1:8000
zuko files # foreground dufs server + authenticated tunnelSession notes:
- Real host PTY; bytes are forwarded verbatim.
- Detached PTY lease: 5 minutes. No replay buffer.
- Use
tmux,zellij, orscreenfor durable work. - CLI force-exit: Ctrl-C three times within ~1s with no remote output.
Run zuko tunnel <port> inside a shell opened through Zuko. The native client
binds an ephemeral loopback port, prints it, and opens its HTTP URL for the
common local-web-server case. Traffic is raw TCP: Zuko does not parse HTTP or
terminate TLS, so the printed port also works with HTTPS, WebSockets, SSH, and
other TCP clients.
# On the host, inside the connected shell:
python3 -m http.server 8000 --bind 127.0.0.1 &
zuko tunnel 8000The command remains in the foreground and reports connection/byte totals.
Ctrl-C closes the Iroh tunnel and client port. See
docs/tunnel.md.
For a temporary writable file browser, run zuko files from the directory to
share. It uses dufs from PATH, or installs pinned dufs through mise when
missing, binds it to host loopback, and keeps both dufs access logs and tunnel
statistics in the foreground. The required dufs -A mode grants anonymous
upload, deletion, archive, search, and symlink access through the temporary
client-loopback URL. Press Ctrl-C as soon as sharing is finished.
Run a GUI app inside an existing zuko shell. Output is Kitty graphics over the same PTY/Iroh connection. This is an optional Labs feature, not a remote-desktop goal.
zuko app --list
zuko app firefox
zuko app --doctorSee docs/app.md.
Linux contributors use a version-pinned Ubuntu 24.04 Distrobox as the primary
development environment. Enter it and activate Mise before running repository
commands; docs/building-clients.md lists the box,
system, Android, and platform prerequisites.
mise trust
mise bootstrap
eval "$(mise activate bash)"
hk install --mise # local format and full pre-push checks
just check
just test-e2e # live Iroh network + PTY
cargo build --releasePlatform prerequisites, Windows PowerShell commands, signing behavior, and artifact paths are in Building clients.
| Path | Contents |
|---|---|
src/ |
Rust crate: host, CLI client, handoff, service, and app streaming |
flutter/ |
Shared Android, iOS, macOS, web, Linux, and Windows client |
Justfile |
Human-facing build, test, package, and release recipes |
mise.toml |
Pinned tools, environment, and bootstrap system dependencies |
docs/ |
mdBook docs |
tests/e2e.rs |
ignored live-network integration test |
.github/workflows/ |
Rust, Flutter, release, TestFlight, and docs CI |
Shell access requires both host connection information and an authorized client
token. zuko share transfers the former and registers the latter over an
end-to-end-encrypted handoff. Keep both private and revoke lost clients with
zuko rm <name>.
Report vulnerabilities via GitHub Security Advisory. Details:
docs/security.md.
Apache-2.0. See LICENSE.