Installation
Terminay ships as a desktop app for macOS and Linux, and as a standalone server you can run on a Linux host and reach from the desktop app. Every build is published on GitHub Releases.
Desktop App
Download the asset for your platform. There is no published Windows build.
| Platform | Asset |
|---|---|
| macOS 12 or newer, Apple silicon | Terminay-Mac-<version>-Installer.dmg |
| GNU/Linux x64 | Terminay-Linux-<version>.AppImage |
Each asset carries a .sha256 sidecar. Verify it from the directory you downloaded into before installing.
shasum -a 256 -c Terminay-Mac-<version>-Installer.dmg.sha256On macOS, open the DMG and drag Terminay to Applications. The build is signed and notarized, so it opens without a Gatekeeper override.
On Linux, make the AppImage executable and run it.
chmod +x Terminay-Linux-<version>.AppImage
./Terminay-Linux-<version>.AppImageServer On Linux
Terminay Server runs your terminals, files, and project state on another machine. Installing it is one command on the machine you want to reach.
sudo npx terminay daemon installThat resolves the newest release, verifies its checksum and Ed25519 signature against a key built into the installer, unpacks it, writes a systemd unit, and starts the service. The archive bundles its own pinned Node runtime, the native PTY addon, and the workspace UI it serves, so the host needs neither Node nor a compiler.
Supported hosts are GNU/Linux x64 and arm64 with systemd and a Debian 12-compatible userspace (glibc 2.36 or newer). There is no way to skip verification: the key built into the installer is the only thing that makes the download trustworthy.
The installer asks two questions when it has a terminal. The first is whether to install a system-wide service or one owned by your login. The second is which account the server and its terminals run as — that choice decides whose files, keys, and agents a paired device can reach, and a dedicated terminay account is the default. Answer both up front with --system or --user and --run-as <user>, which is also required when there is no terminal.
You can install something other than the newest release:
sudo npx terminay daemon install v4.1.1 # a specific release
sudo npx terminay daemon install main # the rolling main channel
sudo npx terminay daemon install my-branch # built from source on the target
A branch or commit has no published archive, so the installer builds one on the machine after checking for git, python3, make, and a C++ compiler.
Connect The Desktop App To It
Ask the server for a pairing code and approve the device that scans it, in one terminal:
sudo npx terminay daemon qr-codeThat prints a scannable QR code and the pairing URLs, then waits. When a device asks to enrol, it shows you the device name and a match code and asks you to approve it. Approve only if the code matches the one on the device. Paste the URL into Add connection in Terminay Desktop if you would rather not scan.
The pairing secret lives in the URL fragment and is short-lived and single-use. A paired device reconnects afterwards from its saved profile alone, with no link involved. On a machine with no terminal to approve from, use the scripted commands instead:
npx terminay daemon approvals
npx terminay daemon approve <approval-id>
npx terminay daemon deny <approval-id>Reaching It From Elsewhere
By default the server exposes itself both through the hosted relay and directly, and derives its direct origin from the machine's primary address. That is right for a host with a routable address and wrong for one behind NAT or with a DNS name, so the derived value is printed at install and can be overridden.
sudo npx terminay daemon install \
--direct-origin https://box.example.com:8443 \
--expose hosted,direct \
--port 8443Direct mode is authenticated by the server's host key, not by TLS. The listener presents a certificate the server generates into its own data root; a client verifies the host key's signature over the transport transcript before any credential crosses, so that certificate is not something to distribute or pin. Browsers cannot accept a self-signed listener, so direct mode is for the desktop app — keep a reverse proxy with a real certificate if you want browser access too.
Keeping It Running
npx terminay daemon status # unit state, version, channel, exposure
npx terminay daemon upgrade # follow the installed channel
npx terminay daemon start
npx terminay daemon stop
npx terminay daemon uninstall # keeps the data root unless --purge upgrade follows whatever channel the machine is already on, so a host tracking main never silently moves onto the tag stream. It stages the new version beside the running one, switches an atomic current symlink, and puts the previous version back if the new one does not report ready. It refuses to move to an older version unless you pass --allow-downgrade.
uninstall removes the service and the installed versions but keeps the data root, which holds the host key and your paired device records. Add --purge to remove that too — every paired device will have to pair again.
For hosts the installer does not support, the archives are installable by hand. The standalone server runbook documents that procedure along with every configuration option, hosted exposure, backup, and restore.
Build From Source
If a packaged build is not available for your platform, build Terminay locally. The repository pins Node.js 24.15.0 and npm 12.0.2.
git clone https://github.com/markwylde/terminay.git
cd terminay
npm ci
npm run build
Packaged output is written under release/<version>/. Release builds sync the app version from the Git tag before packaging, so local source builds appear under release/0.0.0/.