# sshx: a collaborative terminal on an infinite canvas

> sshx turns a shell session into a shared web page you can pan, zoom and hand to a colleague. Here is what the installer does, how the client and server fit together, and where the project stops short.

**ekzhang/sshx** — Fast, collaborative live terminal sharing over the web

- Repository: https://github.com/ekzhang/sshx
- Website: https://sshx.io
- Stars: 7,671 · Forks: 306
- Language: Rust
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/ekzhang-sshx

## The problem sshx solves for pair debugging

Screen sharing a terminal is awkward. The viewer sees a video stream, cannot scroll back, cannot select text, and cannot copy a command out of the window. sshx takes a different route: the terminal itself becomes a web page, and everyone in the session gets their own viewport onto it. The README lists the mechanics plainly, a single command starts a share, participants resize and move windows on an infinite canvas, cursors from other people move in real time, and the client reconnects automatically while showing latency estimates.

The audience is narrow but real. It suits an engineer who is already on a call with someone and wants them to read the actual output rather than a compressed picture of it. It suits a CI job that fails only in the pipeline, because the README shows sshx being started from a GitHub Actions step so a human can attach to the runner. It does not suit anyone who wants a persistent remote shell for daily work. sshx is a viewing and collaboration layer, not a replacement for ssh itself.

## Client, server and the mesh the README describes

The repository is a Cargo workspace with a SvelteKit frontend. crates/ holds the Rust code, src/ and static/ hold the web assets, and the workspace version in Cargo.toml is 0.4.1, matching the latest tagged release. The client binary is sshx, the server binary is sshx-server, and the Dockerfile builds both into one image, copying the frontend build directory next to the server and starting it with the argument --listen ::.

The transport is gRPC. The workspace depends on tonic and prost, with the tls and tls-webpki-roots features enabled, and on tonic-reflection. That tells you the protocol is generated from protobuf definitions and that the client talks TLS to the server. The README says the service runs on a globally distributed mesh, so the client is expected to pick a nearby node rather than a single origin. Redis appears in compose.yaml as a development dependency, mapped to 127.0.0.1:12601 on the host, which points to server-side state for sessions living outside the process.

On the browser side, package.json shows sshx-xterm, a fork of xterm, plus the WebGL and image addons, argon2-browser for key derivation, and cbor-x for compact message encoding. The README states the encryption is end-to-end with Argon2 and AES. Read together with argon2-browser being a frontend dependency, the design intent is that the browser derives a key rather than receiving plaintext from the server. The README does not publish a protocol specification, so the exact key exchange is something you would have to read out of the source.

## Installing sshx and starting a first session

The documented install path is a shell script served from the project's own domain. It detects the platform and writes the binary. The README notes that Linux and macOS builds cover x86_64 and ARM64, plus ARMv6 and ARMv7-A, and that the Linux binaries are statically linked. Windows binaries exist for x86_64, x86 and ARM64, linked against MSVC.

```bash
curl -sSf https://sshx.io/get | sh
```

To try it without installing anything, the same script takes a run argument. The README says this opens a remote terminal session and prints the URL, and that it should take under a second.

```bash
curl -sSf https://sshx.io/get | sh -s run
```

On macOS there is a Homebrew formula as well.

```bash
brew install sshx
```

The README points at the script itself for additional options, which is the honest answer: the flags are not enumerated in the README, so read the script before piping it into a shell. If you want to build from source instead, the documented command is cargo install --path crates/sshx, which compiles the client and places the binary in ~/.cargo/bin. There is no documented Windows install command beyond the existence of binaries.

## Running sshx inside a CI job

The README gives a GitHub Actions example rather than a packaged action, on the grounds that a single command does not need one. The step runs the same installer with the run argument, and the comment in the example states that this opens a remote terminal session and prints the URL.

```yaml
name: CI
on: push

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      # ... other steps ...

      - run: curl -sSf https://sshx.io/get | sh -s run
```

The README makes the same point for GitLab CI, CircleCI, Buildkite and CI running on a Raspberry Pi. It also carries a warning that deserves to be repeated: be careful adding this to a public repository, because any user can view the logs of a CI job while it is running. On a public repository, that log line is the shared secret. If the URL is printed to a log that strangers can read, the session is open to them for as long as the job runs.

## Where sshx is the wrong tool

The README states that self-hosted deployments are not supported at the moment, and then lists what a deployment would require: HTTP and TCP reverse proxies, gRPC forwarding, TLS termination, private mesh networking and graceful shutdown. That is not a missing feature flag. It is a description of the work the maintainer already did for the hosted service and has not packaged for anyone else. The Dockerfile exists and the compose file exists, but the README explicitly says not to run the development commands in a public setting because they are insecure. Treat the container as a development artifact, not a deployment recipe.

The second constraint is architectural. A shared terminal is a shared credential. Anyone with the link sees the session, and the README offers no mention of per-participant permissions, session expiry, or an audit trail. For a shell that has production credentials loaded, that is a serious gap. The project is also not a remote access tool in the ssh sense: there is no documented key management, no port forwarding, and no persistent host you log back into later.

A third limitation is documentation depth. The README covers installation and development, but the protocol, the encryption handshake, and the server's session model are not described there. If your threat model requires understanding the key exchange, the README will not get you there.

## How sshx differs from a browser terminal such as ttyd

ttyd takes the opposite approach to the same surface. It runs as a small server you host yourself, exposes a single command as a web terminal, and leaves authentication and TLS to whatever you put in front of it. The trade is clear: ttyd gives you control of the host and the network path, and asks you to handle the operational work. sshx gives you a managed mesh and a collaborative canvas, and asks you to accept that the traffic goes through servers you do not run.

That difference shows up in the collaboration model too. ttyd shares one terminal view. sshx, per the README, gives each participant an independent viewport with their own cursors on a pannable canvas, plus automatic reconnection and predictive echo borrowed from the Mosh idea of local editing. If your need is a single read-only window into a build log, ttyd's model is simpler and you own the whole path. If your need is two people pointing at the same output while one of them types, sshx is doing work ttyd does not attempt.

## Maintenance, licensing and the cost of upgrading

The repository is not archived, and its last push was on 2026-09-21, one day before this was written. That is a live repository. The release cadence is slower than the commit cadence: v0.4.1 was tagged on 2025-02-12, following v0.4.0 the day before and v0.3.1 on 2024-12-30. Anyone pinning to a tag should expect to sit on it for a while, and anyone tracking main should expect unreleased changes.

Upgrade cost is low on the client side. The installer fetches a binary, Homebrew handles the macOS case, and cargo install rebuilds from source. There is no database migration or config file to carry forward that the README mentions. The server is the part you cannot upgrade yourself, because you are not running it.

The licence is MIT across the workspace, declared in Cargo.toml and shipped as a LICENSE file at the repository root. MIT permits commercial use and modification with attribution and no warranty. That covers the code. It does not tell you anything about the hosted service at sshx.io, whose terms are not part of this repository. If you plan to route work traffic through the hosted endpoint, the repository is not the document that governs that.

## Conclusion

Adopt sshx when you need a second pair of eyes on a shell and you are comfortable sending the session through the hosted service at sshx.io. Do not adopt it if your policy forbids third-party relay of terminal traffic, or if you need a supported self-hosted install, because the README states self-hosted deployments are not supported and warns against running the development commands publicly. Before you rely on it, verify the end-to-end encryption claim by reading the client and server sources in crates/, and confirm that the URL printed by the run command is the one your collaborators actually open.

## FAQ

### How do I install sshx using the command prompt?

The README gives a single installer command, curl -sSf https://sshx.io/get | sh, which fetches the binary for your platform. On macOS you can use brew install sshx instead, and the README points at the script itself for additional options.

### What is sshx?

sshx is a web-based collaborative terminal. The README describes running one command to share your terminal with anyone, with participants seeing each other's cursors on an infinite canvas and the connection protected by end-to-end encryption using Argon2 and AES.

### Can I self-host an sshx server?

The README states that self-hosted deployments are not supported at the moment, and lists the reverse proxying, gRPC forwarding, TLS termination and mesh networking a deployment would need. It also warns against running the development commands in a public setting because they are insecure.

### Which platforms does the sshx client support?

The README says Linux and macOS builds cover x86_64 and ARM64, plus embedded ARMv6 and ARMv7-A, with Linux binaries statically linked. Windows binaries exist for x86_64, x86 and ARM64, linked to MSVC.

### How do I build the sshx client from source?

The README says to clone the repository and run cargo install --path crates/sshx with Rust installed, which compiles the binary into your ~/.cargo/bin folder.

## Sources

- [ekzhang/sshx on GitHub](https://github.com/ekzhang/sshx)
- [License: MIT](https://github.com/ekzhang/sshx/blob/main/LICENSE)
- [Project website](https://sshx.io)
- [README](https://github.com/ekzhang/sshx/blob/main/README.md)
- [Releases](https://github.com/ekzhang/sshx/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ekzhang-sshx
