GoTTY: Share a Terminal Command as a Web Application
Share your terminal as a web application
At a glance
- What is it?
- GoTTY wraps a CLI command in a PTY-backed WebSocket web server. It is simple to install and useful for demos and read-only sharing, but the write path and TLS story need care before you expose it.
- Who is it for?
- GoTTY fits engineers who want to expose a single CLI command to a browser with one binary and no application code: a build log, a dashboard, a demo. It does not fit multi-user shells on a public host, because --permit-write hands over the TTY and the default listener is 0.0.0.0:8080.
- 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 57 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What GoTTY turns into a web page
GoTTY is a command line tool that runs another command and serves its terminal session to a browser. The README states the goal plainly: it "turns your CLI tools into web applications." The usage line is `gotty [options] <command> [<arguments...>]`, so the unit of work is one command plus its arguments, not a shell session in general. `gotty top` is the example the README gives.
The audience is narrow on purpose. Someone who has a process that only exists as a terminal program, and who wants a URL that shows it, is the intended user. That includes build watchers, log tailers, and single-purpose TUI programs. It is not a remote desktop, not a shared shell for a team, and not a replacement for SSH. The project is MIT licensed and written in Go, so the deliverable is a single static binary per platform rather than a runtime plus dependencies.
The PTY, WebSocket and xterm.js path from command to browser
The repository layout shows the split: `backend/` holds the PTY and command execution side, `webtty/` holds the WebSocket transport, `server/` holds the HTTP server, and `js/` holds the browser client. The `go.mod` file lists `github.com/creack/pty` and `github.com/gorilla/websocket` as direct dependencies, which matches that structure: the command runs under a pseudo-terminal, and terminal bytes travel over a WebSocket to a browser-side terminal emulator built on xterm.js (the Makefile copies `@xterm/xterm/css/xterm.css` into the embedded assets).
On the server side, assets are embedded. The Makefile builds `bindata/static/...` entries from `resources/`, and the build tag `dev` switches webpack into development mode while the default build is production. The Dockerfile shows the full pipeline: a Node stage runs `make bindata/static/js/gotty.js.map`, a Go stage runs `make`, and the runtime image is Alpine with `ca-certificates` and `bash`, ending at `CMD ["gotty", "-w", "bash"]`. That final line is worth reading twice. The shipped container starts with write access enabled and a bash shell behind it.
Installing GoTTY and running your first command
There are three documented install routes. The release page carries prebuilt binaries; the README warns that a release marked `Pre-release` is built for testing and can include unstable or breaking changes, and tells you to download the one marked Latest release instead. Files named with `darwin_amd64` are the macOS builds. Homebrew is the second route:
brew install sorenisanerd/gotty/gottyThe third route builds from source and is explicitly labelled development: the README says `go get` builds from the latest master branch, which can include unstable or breaking changes, and that GoTTY requires go1.9 or later.
go get github.com/sorenisanerd/gottyWith the binary in place, start a command and open the default port. The README states GoTTY starts a web server at port 8080 by default, bound to `0.0.0.0` per the options list.
gotty topYou should see the running command in the browser as if it were on your terminal. Defaults can also live in `~/.gotty`, which GoTTY loads when it exists. The README's example sets a port and enables TLS:
port = "9000"
enable_tls = trueThe config file uses HCL syntax (the `github.com/yudai/hcl` dependency), not TOML, so the example above is illustrative of the key names rather than the file format. Check the repository's `.gotty` file for the full option list.
Write access, origins and TLS: the parts that decide exposure
The single most consequential flag is `--permit-write, -w`, described in the options list as permitting clients to write to the TTY, with the parenthetical "BE CAREFUL". Without it, viewers are spectators. With it, anyone who reaches the URL types into the process. The Dockerfile's `CMD ["gotty", "-w", "bash"]` therefore ships a container whose default state is an interactive shell for whoever connects. That is a deliberate demo choice, and it is the wrong default for anything reachable from a network you do not control.
The mitigations in the option list are partial. `--credential` adds HTTP Basic Authentication in `user:pass` form. `--random-url` appends a random string, 8 characters by default, which is obscurity rather than authentication. `--once` accepts one client and exits on disconnection, and `--max-connection` caps concurrent clients. `--ws-origin` takes a regular expression matching accepted origin URLs, and the help text notes that no cross-origin requests are acceptable by default, so opening the WebSocket to another origin is an explicit act.
TLS is opt-in through `--tls`, with certificate and key paths defaulting to `~/.gotty.crt` and `~/.gotty.key`, and an optional client CA at `~/.gotty.ca.crt`. Nothing in the README suggests a self-signed certificate is generated for you, so you supply the files. `--close-signal` defaults to SIGHUP and `--close-timeout` defaults to -1, which the option list describes as the time in seconds to force kill the process after the client disconnects; the default of -1 means that behaviour is off unless you set it. If your command ignores SIGHUP, it can outlive the browser tab.
Where GoTTY is the wrong tool
GoTTY shares one command with many viewers, and the option list reflects that model rather than a multi-user one. There is no session isolation, no per-user shell, no scrollback persistence beyond what the browser keeps, and no documented audit trail. `--reconnect` exists to let a browser reconnect, but the README does not document what happens to the running process across a disconnect beyond the close signal and close timeout options.
The documentation is also thin in places that matter for production. The README does not document rollback, does not describe rate limiting, and does not state what happens when a client disconnects mid-command under the default `--close-signal SIGHUP`. The display customization section, which covers six built-in themes, fonts and cursor style, plus a runtime picker that persists to browser localStorage, is more developed than the operational guidance. If your requirement is a hardened bastion host with per-user accounting, this is the wrong layer: GoTTY hands a terminal to a browser, it does not decide who deserves one.
GoTTY against ttyd and the original yudai/gotty
The closest comparison is ttyd, which people search for alongside GoTTY. Both expose a command over a WebSocket to a browser terminal, so the difference is not conceptual but in packaging and defaults. GoTTY's README documents a Homebrew tap, prebuilt release binaries, a `~/.gotty` config file, an option set covering Basic auth, random URLs, TLS with an optional client CA, connection limits and WebSocket origin matching, and a Dockerfile that builds a bash-in-a-browser image. The README does not include a ttyd feature comparison, so any claim about which is faster or lighter would be speculation.
The other reference point is upstream. GoTTY in this repository is a fork; the README credits the original work by Iwasaki Yudai and links to `github.com/yudai/gotty`. If you find older tutorials, they most likely target that upstream project, and option names or behaviour may differ. The fork's own version history is visible in the releases and in `NEWS.md`.
Maintenance, licence and upgrade cost
The last push to the default branch was on 2026-08-05, and the most recent release listed is v1.8.0 from 2026-05-24. The repository is not archived. That is recent enough that the project is being touched, but the README itself does not promise a support policy, and there is no documented deprecation window for options.
Upgrade cost is mostly the Go toolchain and the embedded frontend. `go.mod` declares `go 1.26.0`, so building from source requires a matching toolchain; the README's go1.9 note applies to the historical `go get` path. The Dockerfile pins `golang:1.26` and `node:22` for the JS build stage, so container builds pull two toolchains. Because the browser client is compiled into the binary through `bindata/`, a frontend change means rebuilding, not swapping a file.
The licence is MIT. That is permissive: it allows commercial use, modification and redistribution provided the copyright notice and permission notice are kept. This is a description of the licence text, not legal advice; if you redistribute a modified binary, read the LICENSE file in the repository and get your own counsel on notice placement.
Editorial conclusion
GoTTY fits engineers who want to expose a single CLI command to a browser with one binary and no application code: a build log, a dashboard, a demo. It does not fit multi-user shells on a public host, because --permit-write hands over the TTY and the default listener is 0.0.0.0:8080. Before adopting it, verify the release you download is marked Latest release rather than Pre-release, and confirm whether your deployment needs --tls and --credential set explicitly.
Frequently asked questions
What does GoTTY do?
It is a command line tool that turns CLI tools into web applications by running a command and serving its terminal session to a browser. The README gives `gotty top` as the basic example, with a web server on port 8080 by default.
What is the GoTTY alternative to ttyd?
ttyd is the usual comparison because both serve a command to a browser terminal over a WebSocket. GoTTY documents its own install routes, a `~/.gotty` config file, and options for Basic auth, random URLs, TLS and WebSocket origin matching; the README does not compare the two directly.
How do I install GoTTY?
Download a binary marked Latest release from the releases page, or use Homebrew with `brew install sorenisanerd/gotty/gotty`. The README also lists a `go get` route but warns it builds from the latest master branch and can include unstable or breaking changes.
Does GoTTY let clients type into the terminal?
Only if you pass `--permit-write`, which the options list flags with "BE CAREFUL". Without it clients are read-only. The Dockerfile's default command uses `-w` with bash, so the shipped container starts with write access on.
Is GoTTY a Scrabble word?
This is a question about the word rather than the software, and the material for this project says nothing about it.
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/sorenisanerd-gotty)