TRMNL ships command-line developer kit in a few days

How a hardware startup shipped a polished command-line app in a few days—without a dedicated team or months of development

Screenshot of usetrmnl.com website

TRMNL faced the daunting challenge of turning a successful Kickstarter idea into real hardware, shipped to thousands of eager customers. On top of that, they needed to deliver a developer SDK with a command-line interface—but building one from scratch wasn’t an option because the company didn’t have enough developers to build it.

Fortunately, the founder of TRMNL, Ryan Kulp, found Terminalwire.

How TRMNL shipped their CLI to production in an afternoon

TRMNL knew they wanted to ship a command-line interface for their SDK because they’re fast, efficient, can be scripted, and loved by developers. Ryan thought building a CLI that would require the resources of a Series B company—then he discovered Terminalwire.

Took less than an hour to get to that “aha” moment

Ryan installed the Terminalwire Rails gem, ran the rails g terminalwire:install command, added a few commands, and had a working command-line interface that he put in front of his customers for feedback.

Developers manage TRMNL plugins from the command-line
trmnl
Commands:
  trmnl go              # Interact with your TRMNL account + native plugins
  trmnl help [COMMAND]  # Describe available commands or one specific command
  trmnl login           # Log in to your account
  trmnl logout          # Log out of your account
  trmnl plugins         # Interact with your custom plugins
  trmnl version         # Displays current CLI version.
  trmnl whoami          # Displays current user information.

Terminalwire is the type of tooling that makes Rails and Ruby thrive.

Customer feedback quickly gets deployed to production

Soon after Ryan shipped the first iteration of the command-line app, a customer reported that two-factor authentication was missing. Ryan built the feature and deployed it to production in under two hours—something that would have taken days with the traditional way of building command-lines.

Screenshot of Discord chat showing how Ryan shipped a feature in a few hours

Focus on designing incredible developer experiences

When Ryan needed to add new features to trmnl, he wrote CLI code that looked like CLI code.

# The `trmnl whoami` command displays login state.
desc "whoami", "Displays current user information."
def whoami
  if current_user
    puts "Logged in as #{current_user.email}."
  else
    puts "Not logged in. Run `#{self.class.basename} login` to log in."
  end
end

The Terminalwire Server streams stdio and stores an encrypted cookie for current_user on the users’ workstations in a way that’s familiar to web developers.

You want another feature? Just write another Ruby function.

Terminalwire made it possible for Ryan to implement this feature, and many other features, in a few minutes by eliminating the time-consuming toil of building, integration testing, and deploying changes to a client and server repo.

The bulk of the work here is NOT thinking about CLIs, it’s not speed or backward compatibility—it’s really just about design. How can we make it intuitive?

Ryan quickly realized with Terminalwire, more time could be spent focusing on designing the developer experience instead of worrying about all the plumbing traditionally associated with command-line interface apps.

Terminalwire takes care of the hard stuff

One reason TRMNL can move so fast with their command-line interface is because of all the heavy lifting Terminalwire does for them, including cross-platform binaries, installers, and software updates.

This type of tooling is the smarter, not harder … it’s what bootstrappers need. I need to get the whole thing live on my own.

These standard Terminalwire features did all the heavy lifting so TRMNL could focus on their core product:

One-line curl installer

The only thing TRMNL customers have to do to install the trmnl CLI is run the following from their workstation.

Install the `trmnl` CLI
curl -Ls https://trmnl.terminalwire.sh | bash

Terminalwire detects which operating system the user is running, installs the appropriate Terminalwire thin-client, then points it at TRMNL’s CLI server.

All TRMNL has to do is tell their customers to copy the command and paste it into their terminal.

Cross-platform binaries

The Terminalwire thin client runs on macOS, Linux, and Windows Linux Subsystem.

Someone can spend a few hours building a CLI and look attractive to their customers against an incumbent

When TRMNL wants to add a feature to their command-line they make changes to code in their Rails app, deploy it to their server, and customers instantly get the new updates streamed to their Terminalwire Client.

Privacy & security

Terminalwire was designed to be familiar to people who build web apps. Want to implement login? Terminalwire has a session feature that lets TRMNL store their users’ login state, and other session data, in an encrypted, signed file on their users’ workstations.

class ApplicationTerminal < Thor
  include Terminalwire::Thor

  def authenticate_user!
    return true if current_user

    shell.say "Must be logged in to do this."
    false
  end

  def current_user=(user)
    session["user_id"] = user.id
  end

  def current_user
    @current_user ||= User.find_by_id(session["user_id"])
  end
end

Direct connections between TRMNL and their customers are over encrypted WebSockets—nothing passes through Terminalwire.

TRMNL punches above their weight with a command-line as polished as stripe and github

Someone can spend a few hours building a CLI and look attractive to their customers against an incumbent

Not only does Terminalwire make it possible for companies and startups to ship CLIs quickly and easily, it also opens up completely new opportunities and capabilities.

Terminalwire isn’t a sprawl, it’s a flex. It’s the series B thing. Now it can be worked into the model sooner.

Before Ryan discovered Terminalwire, he thought building and shipping a CLI would require a team that only a Series B round of fundraising could afford—it wasn’t even something that was on the table at such an early stage.

We can open-source our CLI and let people PR into it.

Not only did Terminalwire make it possible for TRMNL to deploy a CLI at such an early stage, but it opened up completely new capabilities like open-sourcing it on Github so they could better engage with their developer community.

TRMNL now has a command-line app that rivals the polish of Stripe and GitHub—but built in days, not months. More importantly, their CLI is now a key part of their product strategy, giving their developers the tools they need for very little effort.