Overview

How it works

Terminalwire streams command-line apps from your server to a thin client on your users' machines.

It does things SSH can’t, like launch web browsers so users can login via Google OAuth or Okta, store cookies on your users’ workstations, manage files, and more.

Setup takes minutes

This is how a Rails developer installs Terminalwire on their app server.

Installs the Terminalwire Server
bundle add terminalwire-rails
Generates starter command-line app files
bin/rails g terminalwire:install

It generates the files needed to build command-line apps.

Write CLI code, not APIs & plumbing

This is the code a Rails developer customizes and deploys to production.

# Code a Rails developer writes to build a
# Terminalwire command-line app
class ApplicationTerminal < Thor
  # Stream Thor from the server to the Terminalwire client
  include Terminalwire::Thor

  desc "open", "Opens blog post in web browser"
  def open(id)
    # Open browser to post on their
    browser.open post_url(id)
  end

  desc "posts BLOG_ID", "Lists posts for a given blog"
  def posts(blog_id = nil)
    # Print's a table to stdio on the client
    table do |t|
      t.header "Title", "Status"
      current_user.posts.where(blog_id:).each do
        t.row it.title, it.status
      end
    end
  end
end

Notice what’s missing? APIs, client-code, integration tests, cross-platform binaries, a CI that builds everything, a separate repo with the CLI app implemented in a different language, and a whole lot of complicated plumbing.

Terminalwire streams commands like puts, gets, browser.open, File.read, and more from the server to the client. It’s like a web browser, but for command-line apps.

Users install your command-line with one command

Terminalwire makes installation a one-step process for you and your users with the one-line curl installer.

Installs `my-app` app on macOS or Linux
curl -Ls https://my-app.terminalwire.sh | bash

The installer handles all of this stuff so you don’t have to:

  1. Detects the operating system your user is running.
  2. Installs the Terminalwire client for the detected operating system.
  3. Configures the $PATH variable automatically so users can run my-app from their terminal.
  4. Installs the my-app command-line app, which points to your server.

Streams from your server, but runs like any other command-line app

Once installed, users run your app like any other terminal app: type in the command my-app and hit enter.

Users run your command-line app like any other terminal app
my-app
Commands:
  my-app help [COMMAND]  # Describe available commands or one specific command
  my-app open            # Opens blog post in web browser
  my-app posts           # Lists posts for a blog
  my-app version         # Prints the version of the CLI

The only difference is the command was sent to your server, processed, then streamed back to the client.

Over-the-air updates are instant and automatic

Know what’s in the my-app binary that your users install? Not much. Just these two lines of text.

#!/usr/bin/env terminalwire-exec
url: "https://example.com/terminal"

This is how your app is kept up-to-date. When your users enter a command like my-app posts, it streams that to your server, in this case https://example.com/terminal. The server parses the command, executes it, streams the output back to the client, and that’s it.

In a lot of ways it works like a web browser, but with a completely different protocol that’s designed for command-line apps.