Rent-a-founder

Terminal-Based User Interfaces in Go

Recently, a number of Go packages to create terminal-based user interfaces popped up. This is great because it allows you to run semigraphical applications on the server. It’s also more secure than implementing a dedicated admin area in your web app because it reduces the attack surface by hiding behind an ssh login.

Here’s an example from Stock Performer where we can monitor the analytics precomputations that happen on the server:

This small program uses github.com/gizak/termui which is great if you need to display small charts. It’s quite fun to watch those little bars move in real-time.

We also needed an admin interface which would allow us to perform some standard administration tasks such as checking a user’s state, invoicing users, or getting some specific information about some types of data in our database. This application wasn’t going to have any charts but instead be more interactive so instead of termui, I chose github.com/jroimartin/gocui. (I can’t show a screenshot here because there would be too much confidential information in it.)

I was able to implement the functionality I needed. Unfortunately, the way to get there was cumbersome at times. There is a lot of dependency on the gocui.Gui object, it’s needed almost everywhere. Communication sometimes happens through errors (e.g. gocui.ErrQuit in SetKeybinding()). Goroutines that update components must be wrapped in the Update() function. But the main issue for me was that I had write most widgets I needed by myself. The View class implements io.Writer and provides some editor-like functionality which is nice. But I was missing basic components such as a one-line text input field.

I looked at github.com/VladimirMarkelov/clui which has a lot of interesting components. It seems to be focused on recreating a mouse-based window system. I don’t like the visual style much but maybe it would have gotten the job done.

Nonetheless, I decided to create a new library for terminal-based user interfaces in Go. It’s called github.com/rivo/tview (it’s based on github.com/gdamore/tcell which is great to work with) and provides a number of components that can be useful if you want to build an app to explore or modify data:

  • Input forms (with input fields, drop-down selections, checkboxes, and buttons)
  • Text views
  • Table views
  • Lists
  • Flexbox and page layouts
  • Modals

Here’s a simple PostgreSQL database browser which I implemented in ~300 lines of code (this Gist has the code):

The following is a presentation of tview which highlights its features. It is actually written in tview itself.