---
title: Improving User Experience with Shell Scripts
teaser: Your shell is an interface too!
tags: shell,user experience
author: Joël Quenneville
published_on: 2015-10-14
---

Earlier this year, we [rewrote the architecture of this blog][blog-arch]. It is
composed of a Rails application (the blog engine) and a separate repository of
Markdown files. Whenever a new commit is made to the `master` branch of the
markdown repo, the blog engine is notified via a webhook and automatically
imports the changes and publishes them.

[blog-arch]: https://thoughtbot.com/blog/blog-in-markdown-deploy-with-webhooks

As an author all you have to do is write a Markdown document and merge to
`master` after getting it reviewed. You don't need to know about the blog
engine, Rails, or webhooks.

_In theory_.

## Previews

Authors like to preview their content before shipping it. Markdown previewers,
although a step in the right direction, created output that was very different
from what a post would look like on production. Not only did they not match the
style of our blog, but they also lacked all the other UI elements that would
normally be present such as the header, tags, and authors.

The blog engine has a local preview mode that reads posts from the local file
system instead of the database. Problem solved!

In solving one problem however, we'd created another. Now authors needed to
install the blog engine locally, run a server, and point it to their local copy
of the markdown repository. In addition, they needed to update the engine as
changes were made to it as well as keep up with versions of Ruby and Rails.

## Addressing the problem

We received a lot of feedback that the process of writing a blog post had become
convoluted and confusing. First-time authors were frustrated with all the tools
they had to set up before they could even start writing. Something needed to
change.

The new approach needed to solve the following:

* Give authors the ability to preview their work in a way that would look
  identical to production
* Completely remove the need for authors to know about the blog engine
* Not force authors to manage Ruby and Rails versions

## Shell scripts to the rescue

We eventually decided to add a shell script ,`bin/server`, to the markdown repo
that would boot a "preview server". The process for authoring a post is now:

1. Write Markdown document
2. Run `bin/server` and preview post in browser
3. Open pull request

All of the complexity that was previously so frustrating is now hidden behind
the `bin/server` command. This script tries to clone or update the latest
version of the blog engine into a temporary directory. It configures the engine
to run in local mode and points it to the local markdown repo. It will also
automatically install the correct Ruby version. Finally, it boots up a server.

Adding a small shell script vastly improved the experience of authoring a blog
post. This was particularly true for our designers. They don't spend their
entire day in the shell and thus have a lower tolerance for arcane processes
that require running a lot of different shell commands.

As someone who was not only an author, but also worked on developing the blog
engine, I had gotten used to all the hoops I needed to jump through. Once we
introduced `bin/server`, I was surprised at how much pain I had previously
considered acceptable.

## Cleaning things up

Iterating on the script idea, we found that authors thought the output
`bin/server` command was both overwhelming and a little confusing. Most of it is
not necessary unless you are debugging. It was time for a second round of UX. We
redirected most of the output into a `server.log` file where it was out of the
way yet still available if we needed to debug. We added better error messaging
and colorized important lines in the output to emphasize function.

![server output](https://images.thoughtbot.com/improving-user-experience-with-shell-scripts/flDz1dFqQIeTUHOI2WQX_Terminal+%E2%80%94+tmux+%E2%80%94+143%C3%9741+2015-10-09+12-07-02.jpg)

## Bonus points

Authors sometimes encounter small bugs in the blog engine. Once we push fixes to
the repo, all authors need to do is re-run `bin/server`, and they will be
running their preview server on the latest code automatically. Although we
didn't set out to build this functionality, it turned out to be a very nice side
effect of our efforts to improve user experience.

## Lessons learned

User experience is important, even for developer tools. Just because you are
comfortable with the terminal doesn't mean that it's not worth improving a
complex workflow.

Just as with user-facing products, get feedback from those that use your dev
tools and iterate on improving the interface and experience.

Distill your workflow to its essential components and hide unimportant details
behind abstractions. Use color and spacing to make the output of your scripts
intelligible and hide information that isn't useful.

## Source code

For those interested, you can view the source for the `bin/server` script in
this [gist].

[gist]: https://gist.github.com/JoelQ/93d10a8805889968e120
