CLI-first devtools

CLI-first devtools

Mobile-first. API-first. Native vs web. These are well understood. But what about CLI-first? Is this a new approach to building devtools? Can you build a good CLI-only product?

Mobile-first. API-first. Native vs web. These are well understood concepts.

The first was common in the early 2010s as the smartphone era kicked off, primarily for consumer apps. Facebook famously shifted to mobile after initially being all-in on the web.

Then came API-first, where the product was the API and the UI on top of that was secondary. Obviously targeted at developers, Stripe and Twilio are two of the best examples, but AWS, Azure and GCP are also good examples - the cloud is a data center as an API.

Native vs web is a battle that can be summed up as Google vs Apple, although there are many other players. Google has no native desktop apps - all their products are accessed through the browser. Apple is almost the opposite - all their apps are native and their web versions tend to not be very good. Of course there are exceptions (Google Drive desktop clients, Apple TV+ on the web), and Google has "native" mobile apps (even if they don't use the platform design language on Apple devices).

You might think that developers are well-catered for by APIs. An API is the preferred way to integrate with another service, but is it the preferred way to manage it?

Developers integrate with AWS's products with APIs, but do they want to manage them via the AWS web console? IaaC using Terraform is probably preferred.

Developers send messages via Twilio's APIs, but do they want to log into the web UI to manage their account and access logs?

Developers send all their logs and metrics via Datadog's APIs and agent, but do they want to log into the web UI to configure settings and tail the logs? It's not Nagios, but Datadog's web UI is complicated.

The majority of the development experience is via the code editor and command line interface - working with Git, installing packages, running tests - but getting code to production still requires working with a lot of sub-par management interfaces.

CLI-first

There is an interesting trend with the newer breed of devtools: CLI-first. In these cases, the command line interface is the primary (and sometimes only) interface to the product. The goal is to show value to the user with the minimum number of commands - three is enough to get going:

packagemgr install toolname
toolname signup
toolname create --some --options

From there, a world of power-user options via sub-commands opens up the product functionality without taking the user out of their development flow. The web UI is either non-existent or optional.

Example: Fly.io (cloud infrastructure)

Fly is a global cloud platform that makes it easy to deploy Docker containers to edge locations around the world.

We featured Fly in the 2022-02-10 Console newsletter. One of my favorite "features" is that everything can be managed via their CLI - indeed, they are only just starting to build out their web UI for billing and user management. Everything else is done via flyctl.

Signing up to Fly launches a web browser (a credit card is required for anti-fraud purposes), but I'm then taken back to the CLI to deploy my first app. The launch command reads in my Dockerfile and a few seconds later I have a running app.

flyctl commands run in the terminal.

Example: PlanetScale (serverless database)

PlanetScale is a MySQL-compatible serverless database platform I've been working with for a side project. A database is a good example where most developer interactions are via a CLI - creating databases, managing connection strings, logging into the MySQL shell, executing SQL queries.

PlanetScale have a good web UI that exposes all the product functionality, but everything can also be done via the CLI. They are equal citizens.

pscale commands run in the terminal.

Example: EdgeDB (database)

Another database example, EdgeDB, specifically highlights their CLI as a way of interacting with the database - creating projects, dealing with migrations, executing queries. It is considered a first-class interface alongside the official database clients for programming against the database.

Marketing screenshot for the EdgeDB CLI.

Why CLI-first?

If your product is focused on the developer as the primary user, it makes sense to meet them where they already are - their editor and the command line.

Installation of CLI tools is easy (Homebrew, Linux packages, Chocolatey or winget). The UI is consistent across platforms. And if you build the CLI well, it will inherit the users's terminal customization (light/dark mode, color themes, fonts, etc).

Terminal interfaces have limitations and constraints. Although interactive TUIs are becoming more popular and there are some interesting UI libraries for building visual interface elements, the UI is essentially text-based. There is also an expectation of good performance, both of which act as limits on how much you can pack into the UI.

Applying the Unix philosophy of simplicity, a CLI command should only do what is absolutely necessary:

Make each program do one thing well. To do a new job, build afresh rather than complicate old programs by adding new "features".

Being compact, minimalist and modular means each command can focus on the job to be done (also one of Console's cultural values). You can present multiple interfaces behind flags and options - perhaps an interactive TUI by default - but also with the ability to pipe the results to stdout in text or JSON.

Expect the output of every program to become the input to another, as yet unknown, program. Don't clutter output with extraneous information. Avoid stringently columnar or binary input formats. Don't insist on interactive input.

Developers are familiar with the common design patterns of commands and sub-commands such as list and status whereas web UIs are all different, inconsistent, and often slow and heavy. A CLI can make it very quick and easy to get started with a product.

Limitations of CLIs

That focus on "getting started quickly" is the key. We try out hundreds of developer tools as part of our review process and the best ones have put time and effort into a smooth onboarding process. Developers want to signup and try a product quickly.

However, CLIs are for technical users by design. "Normal" people want to use a point and click GUI, whether as a native app or a web UI. Even developers may prefer a web console. A CLI hides all the functionality behind a manpage or --help flag, so figuring out how to surface the key features is an important consideration when designing an onboarding flow. Some features may need another way to access them.

This means CLI-first is really all about improving the developer experience as a way to introduce the product to a new user. If the developer has a good experience, it is more likely the product will be adopted within an organization. That's when the web UI comes in.

There are many popular terminal utilities which will only ever be available as a CLI, but they're the ones that remain as side projects. For software businesses, CLI-first doesn't mean CLI-only. Developers are rarely the only user of a product, but having a well-implemented CLI is a good indicator that the product is designed for developers as the primary user. This is especially true if the CLI is part of an already terminal-based workflow (test, commit, push, deploy).

Conclusions

Aside from the classic set of open source terminal emulators like iTerm2, Alacritty, Kitty, and many other awesome terminal utilities, the fight for a place in the developer terminal is heating up. There's a lot of value to being an important tool in the developer workflow.

As more products focus on developers as the primary user, we will see more of this CLI-first approach. Reaching the developer where they already are will be an important way to onboard new users of the product, even if there are features accessed via other interfaces.

Startups like Warp are building an entirely new terminal. Fig are building a way to enhance your existing terminal. Teleport is making it easier to manage the terminal as a route into your infrastructure, and Cased (which we are an investor in) is helping to apply auth controls and team playbooks to the terminal workflow. Even existing products are adding CLIs to improve the developer experience - Twilio has a new CLI in beta and Stripe's CLI allows you to interact with test accounts.

Building a dev-focused product? A CLI is a good place to start.

Building an MVP? A CLI is much easier to build than a full web UI.

Need to onboard devs quickly? A CLI is a good way to do that.

However, most "apps" are unlikely to be CLI-only. Some terminal utilities are only ever going to be used on the terminal. But where there is a larger product, where non-technical users need an interface they understand, where visual components like graphs and reports are important, or where the experience just needs to be built using web tech (real-time document editing, media streaming, viewing PDFs), CLI-first is insufficient.

Thanks to Alana Anderson, Ellen Chisa, Ed Sim, and Guillermo Rauch for providing their thoughts on this trend.

Discover the best tools for developers

Console Newsletter - A free weekly email digest of the best tools and beta releases for developers. Every Thursday. See the latest email.