Making Open Work
May 8–9, 2017: Training & Tutorials
May 10–11, 2017: Conference
Austin, TX

Building amazing cross-platform command-line apps in Go

Steve Francia (Google), ashley mcnamara (Microsoft)
1:30pm5:00pm Tuesday, May 9, 2017
Adopt This Now, Infrastructure
Location: Ballroom F
Level: Beginner
Average rating: ****.
(4.00, 15 ratings)

Who is this presentation for?

  • Developers

Prerequisite knowledge

  • A basic knowledge of programming (in any language)

Materials or downloads needed in advance

  • A laptop with Go (version 1.5 or greater), Git, and the text editor of your choice installed (For people interested in a Go-aware editor, the IntelliJ IDE and the Go plugin work together really well on Windows, Mac, and Linux.)
  • Instructions:
    1. Install Go via brew (Mac), apt-get (Linux), or the MSI (Windows).
    2. Install Go prior to the Go plugin (recommended).
    3. Install the community edition of IntelliJ.
    4. Install the Go plugin.
    5. For those partial to vim, the vim-go plugin is excellent and is included in the spf13-vim distribution.

What you'll learn

  • Understand the importance of CLI tools and the Go language


Once thought relics of a mouseless age, command-line interfaces (CLIs) are making a huge comeback in a new and evolved form. Go is an excellent platform for CLI development due to its raw power, easy syntax, and painless distribution. We can build much better applications then we are currently doing. So much work in recent years has gone into usability and design on the Web and mobile, but the command line is often forgotten—in spite of a dramatic rise of command-line programs being developed. Through awareness and better libraries, we can spark a movement into better interfaces.

Ashley McNamara and Steve Francia outline the techniques, principles, and libraries you need to create user-friendly command-line interfaces and command suites before walking you through building your own app. Along the way, you’ll cover everything from how to design and build commands to working with and parsing flags, config files and remote config systems, and how to work with environment variables and 12-factor apps. By the end of the workshop, you’ll have a working knowledge of Go and your very own functioning CLI app.

Photo of Steve Francia

Steve Francia


Steve Francia is a Gopher at Google as well as an author, speaker, and developer. Steve is the creator of Hugo, Cobra, spf13-vim. Previously, he was an exec at Docker and MongoDB. Steve serves on the board of Drupal.

Photo of ashley mcnamara

ashley mcnamara


Ashley is a tech industry veteran, starting from homebrew hardware all the way through cloud advocacy, community management, and mentorship. She is currently a Developer Advocate for Microsoft, with a focus on Cloud Native tools and the Go community. She is an active chapter leader and mentor within the Women Who Go community and also on the board of the GoBridge foundation. Her passion is helping more underrepresented individuals join and feel comfortable in tech and being a resource for new developers trying to find their way.

Comments on this page are now closed.


Jeffrey Liu | SDA
05/09/2017 5:40pm CDT

One more thing, seems like you need to take out the conditional assigment in cmd/add.go

err := todo.SaveItems(“/Users/spf13/.tridos.json”, items)

should just be
err = todo.SaveItems(“/Users/spf13/.tridos.json”, items)

Jeffrey Liu | SDA
05/09/2017 5:17pm CDT

oops the return code was incorrect.

should have been
return items, nil


Jeffrey Liu | SDA
05/09/2017 4:48pm CDT


Was not getting any output from ReadItems (todo/todo.go)

When I added a fmt.Printl(string(b)) it showed the contects.

func ReadItems(filename string) ([]Item, error) {
b, err := ioutil.ReadFile(filename)
if err != nil {
return []Item{}, err
var items []Item
if err := json.Unmarshal(b, &items); err != nil {
return []Item{}, err

fmt.Println(string(b)) return []Item{}, nil


$ ./tri list


Any ideas?