Ship a command-line developer experience for your SaaS ๐Ÿš€

Developers expect web apps to have a terminal apps as polished as stripe, heroku, and github.

With Terminalwire, you deploy a command-line interface to your server in your favorite language and Terminalwire handles the restโ€”installation, cross-platform binaries, streaming, and software updates.

Trusted by TRMNL

How a hardware startup shipped a big tech developer experience with Terminalwire in a few days

Before Terminalwire

Shipping a CLI would require a team that only a Series B round of fundraising could afford ๐Ÿ˜’๐Ÿ’ธ

After Terminalwire

With Terminalwire, I can ship a command-line app in a few days ๐Ÿค ๐Ÿ’ช๐Ÿ“ˆ

TRMNL had to fulfill 1,325 Kickstarter orders for a WiFi-enabled e-Ink display and a developer-friendly SDK for custom visualizations. With Terminalwire, they shipped a polished developer experience to their users in a matter of days.

Read how Terminalwire helped TRMNL โ†’

How it works

What it takes for a developer to build, ship, and maintain a Terminalwire command-line app

Terminalwire streams command-line applications from the server to a thin-client running on your users workstations. 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 seperate 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, is 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.

Frequently asked questions

Answers to common questions people have about Terminalwire

How is Terminalwire different than SSH?

SSH was created in 1995 to secure, encrypted interactive remote shell sessions. It includes features not needed by modern command-line apps for web applications, such as file transfer, port forwarding, and public-key authentication. Today’s command-line applications for web apps need to do things SSH can’t, like open a web browser on the client to authenticate via the web application.

Terminalwire was built specifically to solve problems that modern command-line web apps demand that SSH can’t. It’s a WebSocket-based protocol that streams standard I/O, and other channels, between a web server and client. This allows you to use your preferred command-line parser within your favorite web server framework to deliver a delightful CLI experience to your users.

How is it licensed?

Free Terminalwire licenses are available personal use and commercial Terminalwire licenses are available for organizations depending on revenue, gross assets, and features. Detailed information on pricing, features, and requirements may be found on the licensing page.

Can I use Terminalwire with other web frameworks?

Yes! Terminalwire is designed to be integrated with any web framework and server that supports WebSockets.

How is Terminalwire different from a REST API?

Terminalwire is a WebSocket-based protocol that streams standard I/O, and other channels, between a web server and client. This allows you to use your preferred command-line parser within your favorite web server framework to deliver a delightful CLI experience to your users.

How does authentication & authorization work?

Terminalwire integrates with your existing web app’s authentication and authorization mechanisms. You can use the same authentication and authorization methods you use for your web app.

Do Terminalwire connections traverse through third-party servers?

No, Terminalwire clients connect directly to Terminalwire servers. The encrypted connection does not traverse through any third-party servers keeping your data between your server and users.

The Terminalwire client does connect to Terminalwire.com to check if the URL for the server is connecting to is licensed. This is done through a separate HTTPS connection that only provides the URL of the Terminalwire server end-point. This license check is then cached for 24 hours to prevent frequent checks. If the license server is unreachable or experiencing service issues and a license check can’t be performed, the client will still connect to the server.

Is Terminalwire encrypted?

Yup. Terminalwire uses the same TLS encryption as your web server and browser, which is WebSockets Secure (WSS) in a production web environment.

Still not sure? Let's talk! ๐Ÿค—

Whether your team is building a new command-line app or simplifying existing infrastructure, I'd love to see how we can work together.

Discuss Your Requirements