rtty: a browser terminal for Linux devices behind NAT
🐛 Access your device from anywhere via the web.
At a glance
- What is it?
- rtty pairs a small C or Go client on the device with the rttys server to give you a web terminal, file transfer and HTTP proxy access to Linux boxes that have no public IP. Here is what the repository documents, what it leaves out, and when a plain SSH jump host is the better answer.
- Who is it for?
- Adopt rtty when you manage Linux devices that sit behind NAT or a mobile uplink and you want a browser terminal without running your own VPN or reverse SSH fleet. Skip it when every device already has a reachable address: a plain SSH server plus an SSH client is less moving parts.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 49 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What rtty solves for devices that have no reachable address
The problem rtty addresses is reachability, not terminal emulation. A Linux device behind carrier NAT, a home router or a factory firewall has no address you can dial from your laptop. The usual answers are a VPN, a reverse SSH tunnel, or a jump host somebody has to maintain. rtty takes a different route: the device opens an outbound connection to a server that does have a public address, and you reach the device through that server from a web browser.
The repository describes rtty as composed of clients and a server. The client runs on the device; the server, rttys, runs on a host with a public IP address and is implemented in Go with a frontend built on Vue. Devices are identified by unique device IDs, which is what lets one server hold many devices and lets you pick the right one in the browser.
The stated audience is enterprise operations: the README calls rtty "ideal for remote maintenance and management of large-scale distributed Linux devices." That framing matters. A single hobbyist box behind a router is a use case, but the design decisions (device IDs, batch command execution across multiple devices, a central server) point at fleets.
How the client and rttys server actually connect
The architecture diagram in the README is short and worth reading literally. Several users with web browsers connect to rttys, which holds a public IP address, and rttys connects out to each rtty client running on a Linux device. The arrows run from users to the server, and from the server to the devices. Nothing dials the device directly.
That means the device only needs outbound connectivity. It also means the server is the single point where sessions are brokered, which is the trade-off you accept in exchange for not touching the device's network configuration.
The transport is a websocket, based on the repository topics (websocket, webssh, webshell) and the fact that the browser side is a web interface. The terminal in the browser is Xterm.js according to the README, with virtual keyboard support for touch devices and window splitting for multiple sessions.
Beyond the terminal, the same connection carries file upload and download and an HTTP proxy mode for reaching a device's web interface. Those are the four things the README advertises: terminal, files, web interface access, and batch commands.
There are two client implementations. The C client is described as ultra-lightweight and aimed at embedded Linux and resource-constrained devices. The Go client lives in a separate repository, rtty-go, and the README says it has the same functions as the C client and is fully compatible, with no extra dependencies and a pure Go build and runtime.
Building the C client and reaching a device from the browser
The repository does not carry a step-by-step install guide in the README. What it does give is the dependency list and the build system, so the path is: install the C client's dependencies, build from source with CMake, point the client at your rttys server, then open the server in a browser.
The C client requires libev as its event loop and inih as the INI parser for the config file. SSL support is optional and comes from one of three backends: mbedtls, CyaSSl (wolfssl), or OpenSSL. If you skip SSL, you get the smaller footprint the README quotes: rtty at 32KB plus libev at 56KB. With SSL the same list adds libmbedtls at 88KB, libmbedcrypto at 241KB and libmbedx509 at 48KB, which is the mbedtls combination.
The top level of the repository contains CMakeLists.txt, a cmake directory, src, tools, and rtty.ini. A typical out-of-tree CMake build looks like this:
cmake -S . -B build
cmake --build buildThe configure step is where you choose the SSL backend and the cross-compilation toolchain, which is exactly the part the README does not spell out. For an embedded target you will be passing a toolchain file or a set of compiler variables to the first command.
Configuration is read from an INI file. The repository ships rtty.ini at the top level, and that file is the reference for the keys your build expects, including the server address and the device ID. Read it rather than guessing key names, since the README does not reproduce it.
On the server side, rttys is a separate repository. The README links it but does not document its deployment here, so treat the server's own repository as the source for how to run it and which port it listens on. Once rttys is up and the client is pointed at it, the device appears in the web interface under its device ID, and the terminal, file transfer and HTTP proxy functions are reachable from there.
If your target is a container or a cloud instance rather than an embedded board, the Go client removes the C toolchain question entirely: the README states it has no extra dependencies and builds and runs as pure Go.
Where rtty is the wrong tool, and the limits the README does not discuss
The clearest limitation is structural: rtty does not remove the need for a server with a public IP address. If you cannot run rttys somewhere reachable, or you are unwilling to route every device session through one host, rtty does not help. You have moved the problem from many devices to one server, which is usually an improvement, but it is still a server to run, secure and keep up.
Second, the server is a concentration of access. Every browser session to every device passes through it, and the README's security section is limited to SSL backends and mutual authentication for the client-to-server link. It does not describe how user accounts, permissions or audit logs are handled. That is a question for the rttys repository, and it is the first thing to check if you are considering this for a fleet.
Third, the documentation is thinner than the feature list. The README lists batch command execution, file management and HTTP proxy support, but gives no syntax, no configuration keys for them, and no examples. For a project whose selling point is operational convenience, the absence of a worked deployment example in the README is a real friction point. You will be reading source and the rtty.ini file.
Fourth, consider what you are giving up compared with SSH. An SSH session gives you port forwarding, agent authentication, known-hosts verification and a mature server that ships with most Linux distributions. rtty gives you a browser UI and NAT traversal. If your devices are already reachable, you are paying a complexity cost for convenience you do not need.
Finally, the C client's footprint numbers are quoted for the client libraries, not for a full system. On a genuinely tight embedded target, the SSL variant adds roughly 377KB of mbedtls libraries on top of the 88KB of rtty and libev, so the no-SSL build is the one that fits the smallest devices, at the cost of an unencrypted link.
rtty against a reverse SSH tunnel or a VPN
The closest alternative in spirit is a reverse SSH tunnel. The device runs ssh with the -R option to expose its own port on a public host, and you connect to that forwarded port. The mechanism is similar in shape: an outbound connection from the device, a public rendezvous point, access from wherever you are.
The difference in approach is what runs on the device and what you get. A reverse SSH tunnel reuses the SSH server already present on most Linux systems, so there is nothing new to install on the device and you keep SSH's authentication and forwarding model. What you do not get is a web interface, a device inventory, file upload and download through a browser, or an HTTP proxy mode for reaching a device's web UI. You also have to manage the tunnel yourself, including reconnection when the link drops.
A VPN such as WireGuard takes the opposite approach: instead of brokering sessions through an application server, it puts every device on a private network and you address them directly. That is more general and gives you any protocol, not just a terminal. It is also more work to operate at fleet scale, and it assumes you can run the VPN endpoint.
rtty sits between those two. It is narrower than a VPN and more opinionated than a raw tunnel, and the thing it adds is the browser-facing layer: Xterm.js in the page, device IDs in a list, file transfer, and a proxy for device web interfaces.
Maintenance, licence and what the repository does not promise
The repository is not archived, and the last push was on 2026-08-12. The most recent release shown is v9.1.0 from 2026-05-07, following v9.0.4 in December 2025 and v9.0.3 in October 2025. That is a release cadence measured in months, not weeks, which is normal for a project of this size and worth knowing if you need a fix turned around quickly.
The licence is MIT, which is permissive and places few obligations on how you redistribute or embed the client. If you ship rtty inside a commercial device image, MIT is straightforward compared with a copyleft licence. This is not legal advice; read the LICENSE file in the repository and get your own review if the stakes are high.
The practical upgrade cost depends on which client you use. The Go client is a single pure-Go binary with no extra dependencies, so upgrading is replacing a binary. The C client is a compiled artifact linked against libev, inih and one SSL library, so an upgrade means rebuilding for each target and re-testing against whatever SSL backend you selected. If you have a fleet of embedded devices, budget for a build pipeline rather than a package upgrade.
The README also notes that the project is officially supported by GL.iNet, and lists other production users. That is a statement about who uses it, not a support contract. The README does not describe a commercial support offering, an SLA, or a security response process.
Editorial conclusion
Adopt rtty when you manage Linux devices that sit behind NAT or a mobile uplink and you want a browser terminal without running your own VPN or reverse SSH fleet. Skip it when every device already has a reachable address: a plain SSH server plus an SSH client is less moving parts. Before rolling it out, decide who operates rttys, confirm which SSL backend your C build links against, and check the rtty.ini in the repository against the options your build actually accepts.
Frequently asked questions
What is rtty and what does it do?
rtty is a remote terminal solution made of clients and a server. The client runs on a Linux device, the rttys server runs on a host with a public IP address, and you reach the device through a web browser using its unique device ID. It also carries file upload and download and an HTTP proxy for device web interfaces.
Does rtty need a public IP address on the device?
No. The architecture in the README shows browsers connecting to rttys, which has the public IP address, and rttys connecting out to each rtty client. The device only needs outbound connectivity to the server.
What are the dependencies for building the rtty C client?
The README lists libev and inih as required. SSL support is optional and uses one of mbedtls, CyaSSl (wolfssl) or OpenSSL. The Go client in the separate rtty-go repository has no extra dependencies and is a pure Go build and runtime.
Can rtty run on a container or a cloud instance instead of an embedded device?
Yes. The README describes the Go client as suitable for rapid integration and cloud-native or container environments, with the same functions as the C client and full compatibility with it. The C client is the one aimed at embedded Linux and resource-constrained devices.
What licence is rtty released under?
The repository states the MIT licence, and the LICENSE file is at the top level of the repository. That is permissive and imposes few conditions on redistribution or embedding.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/zhaojh329-rtty)