My remote pair programming setup

Pair programming is one of my favorite things to do, in many ways I feel way

more productive when I pair with someone else and the cliché that Two (2) heads are better than one seems to be right in this case (at least for me).

Remote pair programming is hard, especially if you use the wrong tools. Since

I’ve been doing this for a long time, I developed a workflow around it with

tools that I think is worth sharing.

Note: I will not go into the discussion of “Why pair programming”, I think

it’s irrelevant for this post and there are many posts on the internet

discussing that point to exhaustion. I think this blog post discusses the ups/downs of pair programming well, read it if you want to learn/educate yourself more.

Tmux

I work with tmux a lot. One of the best thing about

Tmux in the terminal is that once you share your session using SSH, the person

pairing with you has access to all the tabs you have open for the project.

For example, if you pair on a rails project, you can see the console, server

logs, Redis and really just about anything else you have in that Tmux session.

I blogged about how I start work using tmux in the past in these posts

[My development workflow (vim+tmux+terminal+alfred) Awesomeness ](http://avi.io/blog/2014/08/28/my-development-workflow-vim-tmux-terminal-awesomeness/)

How I start working using Tmux

Essentially, I have a start.sh file in every project root that opens all the

tabs/splits I need and gives the session a name.

Configuration

You can check out my tmux configuration in my dotfiles repository here

Note: This is only tested on Mac, I know there are some problems with using it

on linux, especially around attach-to-user-namespace and the use of pbcopy .

Here’s an example of what a tmux session looks like

Edit: Thanks to Reddit user tuxracer04 for suggesting tmate.io. I have tried it before and it’s a very good option to share your session, it requires less setup but you have less fine grained control. Worth a short to test things out

Vim

I use vim in terminal exclusively as my editor. Over time I tried every editor

out there, from Sublime to Atom and more.

Since I am using the terminal as my main work tool, it’s easy to just use vim

inside tmux and share it, this simplifies the workflow of pairing quite a bit,

since you don’t have to screen share your code and deal with delays.

With screen sharing, it’s hard to pair since you need to allow your peer to

drive as well, anything from copy/pasting code to tying something they want.

Obviously, I do not want to make this post an editor war, but I really

encourage you to use a terminal based editor, whether it’s emacs, vim or any

other tool, it will make your life so much simpler

Configuration

I don’t have any pair programming specific vim configuration, it’s just using my

dotvim configuration https://github.com/kensodev/dotvim.

Running tests

Whether I am coding in Go, Ruby or any other language for that matter, I always

do TDD, no exceptions (Yes, even for Javascript)

Running tests is a huge part of the workflow when pairing and looking at

results of tests is definitely something we do a lot while pairing.

The usual “running tests” workflow is very breaking, you need to look at

another screen in order to view test results, or stop looking at code in order

to do that.

With running everything in the terminal and using Tmux, I can basically send

the result of the testing to another split.

Her’s an example of what this looks like

As you can see in the red rectangle, there’s a file called read_pipe.sh , here’s the contents of this file

#!/bin/bash DEFAULT_PIPE_NAME=".plumber" PIPE_NAME="${1:-$DEFAULT_PIPE_NAME}" if [ ! -p $PIPE_NAME ]; then echo "Created pipe ${PIPE_NAME}..." mkfifo $PIPE_NAME fi echo "Waiting for commands!" while true; do COMMAND=$(cat $PIPE_NAME) echo Running ${COMMAND}... sh -c "$COMMAND" done

This comes from vim-plumber,

which allows you to send the results of tests to a pipe file

All I need to do is hit <leader>t or <leader>T in order to run tests, the

tests will run in the background in another pane and I can continue working.

When pairing this is super powerful since you can just run tests and then look

at them, copy results, look at the code while looking at the results side by

side and more.

This saved me so much time over the period I’ve been programming I cannot

emphasize enough how important this workflow is.

What does TDD has to do with pairing

I know it’s weird seeing TDD in a remote pair programming workflow, however, I

feel it’s absolutely crucial to pair when you pair program since TDDing forces

you to slow down and explain the process of your thoughts.

When you TDD, it’s a perfect oportunity to discuss the design with your pair

and understand how the system works.

SSH

In order to share tmux and your terminal you will need to allow SSH into your

machine. This is a bit tricky and requires just a bit more configuration beyond

your machine as well.

Router configuration

It is more than likely that you have a router in your home office, so behind

your public IP there’s a list of internal ip’s.

You need to configure your router that whenever someone SSH’s into the home

address they will be routed into a specific computer.

Every router is obviously different, but it looks like this

I have it configured that my laptop has a fixed saved IP on the router so it’s

always the same address and it does not change, this way it’s easier to make

the configuration sticky.

Authorized keys

In order for someone to SSH into your machine you have to authorize their

public key.

BUT, remember each tmux session has a name, you can actually limit people into

a tmux session when they SSH, if that tmux session doesn’t exist, they won’t be

able to SSH into your machine

command="tmux attach-session -t SESSION_NAME",no-port-forwarding,no-x11-forwarding,no-agent-forwarding KEY_TYPE KEY

SESSION_NAME is the tmux session name you set, KEY_TYPE and KEY are the

name and the key given to you by your peer.

Binding each key to a session name is a very good way to make sure that peers

can only access sessions open for them, if you don’t have the session open, the

SSH will fail.

What I do is I append _pair to my usual session names, lets say I have a

session named gogobot , when I want to pair I will rename the session to

gogobot_pair in order to work with one of my peers. When we’re done pairing,

I will change the session name back to gogobot .

SSH Tunneling

One of the best thing about SSHing into your machine is that now your peer can

access your server, so you don’t really need to share screen to see the browser

even.

This blog post explains SSH tunneling really well, go read it.

Voice / Screen

When everything is in the terminal, this is by far the least important part.

Personally, I use Skype in order for voice and screen share, but I have also

used Google Hangouts and other solutions.

When my peer has trouble setting up the tunneling, we can also look at the

browser together.

Closing thoughts

Before I moved to a 100% terminal based workflow, remote pair programming was

close to impossible.

There are many solutions that try to solve this problem, Screen Hero was one of the best ones before they shut down the product.

https://atom.io/packages/motepair looks

nice if you are using Atom as well.

This post will not be complete without mentioning Joe’s Remote Pair Programming website, this was an inspiration to me for a long time and includes many tips and tricks for making it work.

I hope you enjoyed this post, feel free to leave a comment with

questions/feedbacks, I’d love to hear what you have to say