You have many techniques to choose from when comes to doing real-time collaborative development (which is most typically mobbing or pairing). This article provides some pros & and cons for each technique, based on a good amount of personal experience. The techniques include:
-
Screen share
-
Screen share + remote control
-
Terminal multiplexers
-
File sync-based solutions
-
Cloud-based IDEs
-
Git handover
Is this list complete? I’d love to hear your experiences too. Please drop a note in the comments.
Screen share
Zoom or any other screen share tool will suffice for this approach. I’ve tried numerous videoconferencing tools, and Zoom seems the easy choice here. It has all the features you’ll probably need (including security mechanisms), and has held up well so far given the dramatically increased at-home traffic volumes (despite a hiccup or two in early lockdown days).
Given the simplest interpretation of screen share-based programming, you sit back, fold your arms, and watch as the other person drives. Every once in a while, you pipe in with a comment. Good luck not getting distracted by email notifications or Slack. Let’s call this “watch & snooze.”
Combined with two other key mechanisms—strong-level pairing and git handover, screen sharing is actually a great solution. Read through to end of the article to learn about this powerful combination.
Watch & snooze, however, is not really a solution for collaborative development. Let’s briefly discuss its upsides and downsides.
The upsides: If you’re driving the whole time, what’s not to like? You get to work on your own machine. If you’re not driving, you’ll get in a good nap once in a while (particularly when you let your driving rotations go long, as often becomes typical).
The downsides: You may as well go back to isolated, solo development. Watching someone code on a shared screen is about as close as you can get to the naive, surface-level view of pairing as “two people doing the work of one.”
Screen share + remote control
Remote control interactions are the apparent default for collaborative development. Most if not all the videoconference tools support the ability to control the screen of the person currently sharing; you can also find dedicated screen sharing /remote control tools such as Screen.so. (I’ve used Zoom, WebEx, MS Teams, and GoTo Meeting heavily, and have tried at least a few other like Screen.so.)
The upsides: It’s simple, requires no complex setup, and it’s fast to switch from driver to driver. It also means that people are able to contribute even if they’re unable to build/test/run the software on their own machine.
In some ways, remote control solutions are the simplest, cheapest things that could possibly work. However…
The downsides: You’re working on someone else’s machine and subject to the vagaries of their IDE and keyboard shortcuts. The experience is also usually unsettling: As you type each character, there’s just enough lag involved so that it doesn’t show up until a small fraction of a second later. That may not seem like much. However, mistakes become particularly frustrating, and tedium builds to make for long, tiring day. Add a party with a less-than-stellar internet connection and it becomes almost unbearable. Over time, the experience encourages many devs to gravitate toward increased watching & snoozing.
Can things improve here? Screen.so promises 30-50ms end-to-end latency. That could be just fast enough to remove the frustration component. Unfortunately I still found it sluggish; I also found it lacking in capabilities and a bit unstable (not much unlike my experiences with Screenshare circa 2013). Remote control is a tough problem! Even with an optimal solution, you’ll still be dependent on good internet connections.
For most remote control solutions, the person sharing the screen cannot do anything else while others are driving. This is probably a feature, not a downside.
Terminal multiplexers
The most well-known terminal multiplexers include tmux (or its fork tmate) and screen. These tools allow for multiple remote clients to connect to the same terminal window session simultaneously.
The upsides: It’s fast–you’re transmitting a character at a time, not gobs of megabits. It feels like you’re there.
The downsides: Terminal multiplexers are only for diehard developers, i.e. people willing to master a character-based editor like VIM or Emacs. Configuring things like colors and how keystroke combinations get sent across to the remote end can be a little tricky, as can setting up a truly secure solution. And to be most effective, you’ll need to learn another dozen or so keyboard shortcuts to manage things like split windows.
You’ll also be giving up a number of wonderful powers your IDE provides. While you might be surprised at some of the cool IDE-ish things that VIM or Emacs can do, they still pale when it comes to compiler-dependent techniques like refactoring or the ability to accurately find all function callers.
File sync-based solutions
With a file sync-based solution, changes to files within a project are automatically synchronized with all developers connected to a common session.
VS Code Live Share is probably the most prominent example of a synchronization-based solution. Live Share also offers co-debugging, allowing all parties to participate in stepwise debugging operations.
Floobits, as another example, promotes the notion that you can use whatever editor you want in a sync-based session–as long as it’s an editor for which Floobits has provided the appropriate plugins. So far, Floobits includes support for (neo)vim, Emacs, Sublime Text, IntelliJ IDEA, and Atom.
Changes generally sync fast in a file-sync-based session.
Floobits charges a modest subscription fee for private syncing solutions. VS Code Live Share is free.
The upsides: You get to work in an editor or IDE of your (limited) choice on your own machine, with your own keyboard settings and other preferences, and without noticeable typing lag.
You continue to have autonomy on your own machine: If you want to poke around at another file while someone else is making changes, go for it. Hopefully the autonomy sounds occasionally convenient to you, but don’t consider it a must-have, full-time feature–the freedom can foster disengagement. Most of the time, you’ll want to be watching and conversing as a remote teammate makes changes. That interaction is a key success factor for live code collaboration.
The downsides: If you don’t happen to use one of the IDEs for which Floobits provides a plugin, you’re out of luck. Thankfully, I do use one: I paid well for the all-languages version of IntelliJ IDEA. I’ve invested a good amount in mastering it. No other IDE appears to have anywhere as good refactoring support, which is important to my minute-to-minute development. I don’t think I’d consider Floobits without the IDEA support.
As far as Live Share is concerned: VS Code’s refactoring support for JavaScript (the only language I’ve really used it for) is weak. I decided to abandon Live Share in favor of IDEA a few years ago (for JS development), and wouldn’t really consider it until the refactoring plugins improved considerably.
I have heard from developers who’ve experienced good success using Live Share. I tried it myself on a couple occasions, including one attempt about a month ago. Both sessions were frustrating; things didn’t work as expected and the whole interaction felt clunky.
Floobits was more promising, and the whole concept even more appealing since I could use my own IDEA setup. But during a 3-hour development session, I found that it stopped syncing three times. A full-minute wait fixed the problem two out of the three times. (The third time, restarting IDEA seemed to do the trick.)
I had just started a Floobits paid plan trial, and submitted a ticket regarding the sync lags, but never heard back. I imagine that a lot of support desks—including that of Floobits—have been totally blitzed over the past few months. I get that, but at the same time can’t consider the product as a result.
I just read another developer’s similar story about what they perceived as hang-ups (their solution was to disconnect & reconnect).
Cloud-based IDEs
I’ll be honest: I’ve only messed with cloud IDEs for a few minutes, other than using Cyber Dojo for a few training exercises. (And Cyber Dojo doesn’t really qualify as an IDE, as it lacks all but the most rudimentary editing capabilities.)
Developers invest heavily in IDEA, Eclipse, or VS for good reasons. These tools are generally very flexible, robust, and powerful. The online tools don’t appear to be quite as sophisticated… yet. I suspect cloud solutions will eventually dominate the IDE space.
Right now, for one example, AWS Cloud9 supports gobs of programming languages. But as far as refactoring support is concerned, so far it only provides the ability to rename. No extract or inline function, no change signature, no move function–at least as not as far as the menus show.
(I think Cloud9 supports VIM; any IDEs that don’t are near useless to me.)
If you do opt for a cloud-based IDE, you’ll want to ensure you’re able to bring up your work in an offline IDE for the occasional times when you don’t have internet access.
The upsides: Once cloud-based IDEs support everything you need, what’ll be not to like?
The downsides: We’re not there quite yet. The need to occasionally work offline becomes a concern. Also, it seems like everyone would need to subscribe to the same IDE.
Git handover
When using the simple technique of git handover, the current driver shares their screen and works within their own IDE for whatever short, timed duration (5 minutes?). When the timer sounds, they commit their changes onto a scratch branch in whatever current state, whether or not the code compiles, and push it up. The next developer in turn shares their screen and pulls from the work-in-progress (scratch) branch. When ready to create a real commit, the team squashes all commits from the WIP branch and merges the single commit into the base branch (perhaps master).
If you try doing each git handover manually, you’ll discover it can represent a good amount of overhead and can also be an error-prone process. A handover might end up taking from 30 seconds to a couple minutes. That handover time becomes a problem if you seek short (e.g. 5-minute) driver rotations, as you should.
You might build a few scripts to streamline the handover; just note that there are number of cases to consider. Better, you can choose to use a tool like mob. With mob, the handover process usually takes 5-10 seconds.
The upsides: It’s free (other than the cost of your videoconferencing tool), handovers are fast, and you have the best of all worlds–your world. Your OS, your IDE, your keyboard shortcuts, your shell—all just as you like them.
The downsides: With mob (or your own scripts), it’s possible to get into an awkward state once in a while. If you forgot to do a mob next
, for example, and perhaps end the session there with the intent of abandoning your changes, you’ll have to manually reset the WIP branch. Fixing the problems is usually easy, though, since mob is largely a wrapper around git commands.
If participants are unable to build the software on their machines, or don’t have update access to the repository, git handover probably won’t cut it. For day-to-day members of the development team, this shouldn’t be a problem. But if you want to have guests—the UX expert or your manager—sit in on the experience, they’ll have to resort to (most typically) remote control.
Haven’t experienced git handovers yet? Give it a go; setting up is fairly easy. (Need a hand getting set up? Ping me.) Once you’ve tried it, you’ll likely agree that mob sessions with screen share + git handover are the simplest, cheapest thing that could possibly work.
If you like your IDE, you should keep your IDE.