Building GitHub Pins
One of the more interesting projects I’ve worked on recently is GitHub Pins, a prototype feature I worked on with my colleagues Jon Hoyt and Harrison Tuow at GitHub.
The premise is simple: Let’s have a way to bundle together collections of any kind of GitHub resource—a commit message, a pull request comment, a repo, a project board, a help doc…a link to that obscure settings page you always have to Google for…you get the idea. Basically, anything GitHub exposes via a URI.
Motivation
The motivation came from observing my work patterns and those of my teammates. Over the course of a project, the number of development artifacts to which I’d need ready access—mainly comments and discussion threads scattered throughout various issues and pull requests—would proliferate, and I’d end up with a ton of pinned and open tabs cluttering my browser.
This made re-gaining context a chore. My workday would typically start with opening up Chrome and seeing something like this:
Not terrible…but that’s at the start of the workday. After a few hours, finding such-and-such issue or PR amongst all the open tabs would become an annoying source of friction for me.
Asking around, I found that my experience wasn’t unique: Other adaptations included creating bookmark folders for each project, using a new browser window for each project / set of open tabs, or just using Google as the index to GitHub, so to speak. (That last one seemed somewhat damning of GitHub’s navigation UI, which broke my heart a little. More on that later.) None seemed satisfactory from a UX perspective.
The remedy I came up with, cast as a high-level user story and preliminary feature spec:
Feature: GitHub Pins
As a GitHub user
In order to keep my workspace uncluttered
And in order to find development artifacts seamlessly
I want to store links to frequently-used GitHub resources on GitHub itself
Scenario:
Given I have saved links to a repo, a PR, and an issue comment
When I visit the root url
Then I should see links to that repo, PR, and issue comment
And I should see those styled with the appropriate octicons
Implementation
On the back-end, the implementation rests on a polymorphic many-to-many
association between the users
table and a pinnable_item
, a stand-in for any
model to which we add a polymorphic has_many
call, for example:
# app/models/repository.rb
class Repository < ApplicationRecord
has_many :pins, as: :pinnable_item
end
Because not all pins have pinnable items backed by Rails models, there’s also a
path
column on the pins
table, so that if a pin’s creation is initiated from
a form with no pinnable_item_id
and pinnable_item_type
, we instead persist
the resource’s path and, when rendering pin models in the view layer, display a
generic “link” octicon.
Iterating
When I first shared this idea with Jon and Harrison their enthusiasm was palpable and they breathed life into it in ways that surpassed my own vision for the feature. Jon immediately leapt on a use case from his own experience: a certain frequently-used settings panel he’d often find himself digging for. That provided the impetus for also handling resources not backed by a database record. Another brilliant idea was collecting pins in (eventually shareable, we hoped) collections, to facilitate context-sharing and onboarding: instead of dropping five URLs into slack, drop one. Or just update a shared board.
The stroke of genius of the Pinterest-like interface was all Harrison’s. Instead of cramming pins into a “widget” like those currently on the homepage, we could let them breathe a bit and allow the user to reorder them as desired. The end result was not only aesthetically graceful, but leveraged a well-understood UX idiom to communicate how to use this feature to maximum effect:
Demo
Finally, here’s the finished v1 in action:
Results
Although it never shipped on master
, I had high hopes for GitHub Pins.
Possibly my favorite bit of UI on GitHub is the fuzzy-search feature when viewing a repository (hit “T”, and a drop-down appears letting you fuzzy-search for files in the repo).
It would have been great to build similar functionality for pins—something akin to an application launcher, Atom’s command palette, or Emacs’s Smex. That would go a long way toward improving navigation on the site—instead of using Google as GitHub’s index, hit, say, Ctrl-T, type the first few keystrokes of “Linguist”, and boom—there’s a list of relevant resources, with your pins stacked at the top.