Tools for Remote Software Development and Pair Programming

Brian Cooksey
Brian Cooksey / May 18, 2017

For all the benefits that a remote office offers, there are times when I wish I could roll my chair over to a coworker's desk for a minute and chat through a complicated bug or tough technical decision. Asynchronous communication doesn’t always work for those tricker issues. Thankfully, the last several years have brought a wealth of online collaboration tools geared at developers, making it easier to virtually share a desk. From screen sharing to paired programming, there is a tool that provides the level of collaboration you want.

Video Calls

Mundane, sure, but don’t discredit the effectiveness of a simple call. Often times at Zapier, we find a quick video call is all you need to get on the same page about a feature or talk through a complicated architecture problem. After all, part of working on a distributed team is that everyone is self-directed, able to tackle most challenges that come their way. If you default to tools that encourage in-depth pairing sessions, you may find that two engineers spend time on an issue that could have taken 10 minutes of collaboration and then one engineer’s effort to implement. A call is enough.

Engineering team meeting

As far as options, there is no shortage of video conferencing software out there. We tend to use whatever is handiest to spin up, which is usually or Slack’s built-in calling feature. The key is to find a tool that is reliably high-quality.

Also, a quick side note from experience. Audio-only calls are ok, but a high quality video feed allows you to pick up on the body language of your co-worker, which provides helpful clues as to how much they really understand the topic you are discussing.

Screen Sharing + Remote Control

Sometimes words don’t cut it. When it’s more efficient to show a problem than explain it, a tool that provides solid screen sharing support is a win. We find this style of communication is helpful with walking through a UX flow, diagnosing a bug iteratively (try an input, see result, try another input, see the next result), or exploring log data together. Occasionally, it’s helpful if the tool also allows the person viewing the share to interact with the remote machine, though clicks and keystrokes can lag so much that it’s more painful than it’s worth.

Engineering team looks at AWS Lambda

Our goto’s at Zapier for this are, which has the screen sharing built-in, or Screenhero if the other person needs to be able to drive as well.

Sharing Code Snippets

Have you ever written a one-off script that helped you dissect a problem? Or maybe you just automated a tedious task (likely spending more time on the script than doing it the manual way, but hey, it was fun). What do you do with the fruit of your labor? The code is not really worthing of adding to source control, but it was a pain to write and you don’t want to lose it.

GitHub Gist

This is where snippet-sharing tools like GitHub Gists and JSFiddle come in handy. You can keep that code around without polluting your app’s main repo. On remote teams, these sites can double as a replacement for a shared network drive. At Zapier, we use Gists as the place to dump helper scripts for setting up dev environments, translation files when moving from the data format of one version of an API to another, and a number of other oddball bits of code. Those online snippets are easy to link to from internal documentation and project specs.

Online IDEs and Hosted Dev Environments

Two classes of tools near and dear to developers’ hearts are code editors and virtualized dev environments. Recent years have seen a number of companies tackle the challenge of moving local development to the cloud. Services like Cloud9 and Codenvy provide an online editor/IDE and a fully hosted virtual machine or docker container. This enables devs to code anywhere they have internet regardless of the device used. It also means pair programming remotely is as easy as sharing the online workspace. You edit the same files, click through the same dev server, and, depending on the vendor, have shared virtual terminal shells for running tests and other commands. Some of the tools in this space, like Koding, even provide a way to mount a remote volume and ssh into the cloud environment, allowing for local file editing while still hosting the dev server in the cloud.

Cloud9 dev environment

Although Zapier does not use this suite of tools company-wide, some members of the team use them on side projects and one-off tasks. Ben Peter, one of our Platform Engineers, spins up a project on Cloud9 when he needs a dev environment on the go so he can code from a Chromebook that wouldn’t normally be able to handle the app locally. He’s also found that having the dev environment hosted at an addressable domain helps in cases where he’s building functionality that involves inbound requests (say testing an OAuth2 flow or webhooks).


If a full-on hosted development environment is heavier than what you want, another option is to run your stack locally and open up the port(s) necessary for others to view your work in real-time. There are paid solutions like ngrok you can use to accomplish this. They are quick to setup and don’t require you to muck with any of the firewall settings of your network.

ngrok diagram

You can also go the free route with ssh if you are able to forward ports on your network. Setting up the tunnel is as simple as including the -L option in the ssh command. You can even turn your tunnel into a complete pair programming session by running Screen or tmux. The host starts the session and the remote person joins (detailed instructions for Screen). You now have shared terminals to fire up an editor, run shell commands, and hit the shared local server. Sometimes network latency can be a momentum killer, but I’ve found it to be a solid way to pair program in the past (combined with a video call).

Another neat trick with tunnels that we’ve used at Zapier is as a way to test features that require receiving callbacks from 3rd party services. Specifying localhost:8000 as the callback URL doesn’t always work when testing something like an OAuth2 flow or inbound webhooks, so having a publicly hosted URL that then tunnels to your machine makes it painless to build locally.

Mad Scientist

Let me say upfront that this is not something we do regularly at Zapier, nor would I exactly recommend it. However, it was too much fun cobbling this solution together to not mention it here.

At one of the Zapier retreats, a coworker and I were jamming on a project together in-person and we wanted to setup a paired programming work station. The problem was that we had two laptops, no external mice or keyboards, and no extra monitors. What are a couple devs to do?

Our scrappy solution was to use rsync. We setup a cron job running a bash script every second on one of the laptops that did the following:

  1. Pull files from the remote laptop, skipping files that had been modified more recently on the local system
  2. Push files to the remote laptop from the local laptop, preserving modified times so the systems are in sync

As long as we were a little careful with saving, we could work on files together, keeping up-to-date with each other's changes. Having two separate machines had an added benefit that one of us could go make a change to the backend while the other updated the frontend code, giving true parallel output. We could also each run the server locally, allowing us to click through the site independently when we wanted to chase down different edge cases.

While I may not be able to have a typical whiteboarding session with a teammate–I’ve tried drawing with a trackpad, I’m terrible at it–the benefits of remote work are far greater than the drawbacks. The technology behind these tools is always improving, reducing the friction of a virtual office. And who knows what the future holds in terms of new concepts for how to collaborate. In a few years maybe I’ll be able to put on a VR headset and draw on a virtual whiteboard with a marker in hand.

Load Comments...

Comments powered by Disqus