Introduction
Everybody is smarter than anybody
-- Woody Zuill
In contrast to the common perception of software development being an individual task, mob programming is a software development approach where a group of engineers works together on the same task. Woody Zuill, the so-called “father of mob programming”, was giving a talk and at one point asked the crowd why he and his team would ever work using the mob programming approach. The first answer from the crowd was “to learn together”. This response resonates with our experience as well; learning together is precisely why we adopted mob programming.
A team may have different reasons for adopting mob programming, and may implement the sessions in different ways as well. In this post, I’ll dive into how we leveraged this approach as a learning and team building tool in order to satisfy the evolving needs of our frontend engineering Chapter (in agile development Chapters are a way of grouping individuals with similar skills to organize teams based on expertise). I’ll also mention the benefits we experienced and in the end I hope you’ll consider how mob programming could be a great tool to adopt in your engineering team!
Format and Organization
We built our mob programming sessions on top of the driver/navigator approach in pair programming, keeping a single driver but adding multiple navigators. Our sessions are held Friday afternoons on a bi-weekly basis, typically last an hour, are hosted virtually, and involve the entire frontend engineering Chapter.
In our first mob programming sessions we solved common coding problems such as this String Calculator Kata or these TypeScript type challenges. However, we soon noticed that the benefits of mob programming can be increased drastically if the sessions have a larger goal that aligns with the needs of the team. For this reason we began emphasizing mob programming sessions based on projects.
Our Mob Programming Projects
Mob Documenting Our Codebase and Processes
When I joined ProntoPro in 2021, the frontend Chapter was composed of five engineers (we are now eleven). There came a time, months after I joined, that we went on a hiring spree. Long story short, five engineers would soon be joining us in the coming months. The codebase we were working with at the time was complex in its design: it was a monorepo structured in layers that hosted multiple Web, iOS, and Android applications (still true today). Additionally, we have strict practices when it comes to structuring commits, opening PRs, performing code reviews, deploying to different environments (stage and production)... All of which was undocumented at the time, and there were even some inconsistencies in how engineers applied these practices.
For the reasons above we got the idea of converting our mob programming sessions into what we ended up calling mob “documenting” sessions. As the name implies, instead of working on coding problems, we worked on documenting our codebase and processes. Our goal was to create a root README.md file synthesizing all this information. We don’t have plans to open source our code, but the idea was to have a README such that any developer could read it and understand the basics of working with our codebase.
In our mob programming sessions we typically randomly assign a driver and rotate the driver every ten minutes. The driver usually remains silent while the navigators discuss solutions and dictate the code to the driver. In our mob documenting sessions the driver’s task was more difficult. Instead of silently typing out the code dictated by the navigators, the driver had to speak up in order to synthesize discussions and create agreement over definitions. The role of the navigators also changed as they had to put a greater emphasis on asking good questions to foster more in depth discussions, and on proposing succinct definitions to wrestle abstract concepts.
The mob documenting sessions had clear and tangible benefits, most notably:
- Knowledge sharing: senior engineers had the opportunity to explain unclear concepts to juniors. This was a great exercise for seniors, who had to test their knowledge by trying to explain complicated concepts in a simple manner. On the other hand, it was just as crucial for juniors to speak up so that we could identify the concepts that were the least clear, prioritizing the topics to discuss, and giving a direction to each session.
- Expediting the onboarding process for engineers: on top of what was learned by attending the mob documenting sessions, the result of these sessions was an artifact (the README.md) that scaled knowledge that was up until then only accessible by directly interacting with senior engineers. Now when a new engineer joins our team, they have a wealth of information consolidated in a single place. Conveniently located right at the heart of the codebase they will be working with. Additionally, new engineers had the chance to use these sessions as a trampoline for forming their own personal relationships with other engineers more quickly.
Learning a New Tech Stack by Building a Note-Taking Application
In September of 2022 ProntoPro merged with Armut under the new holding company known as Homerun Technologies. It was at this time that our frontend Chapter was ready to grow again, mixing two frontend teams used to different tech stacks (Angular vs. React). The decision was made to adopt and improve upon the existing ProntoPro frontend tech stack. We therefore created a brand new monorepo to host our future applications. TypeScript, React, Next.js, and React Native remained at the core of our stack. But some old tools were thrown away in favor of new ones. For example we let go of Redux in favor of Jotai and React Query.
Given that these new technologies were new to both ProntoPro and Armut frontenders, we decided to focus our mob programming sessions on learning these tools. For this reason we built a note taking app using Jotai and React Query. We created another repository on GitHub, aptly called frontend-playground
, to host this application and any future mob programming projects.
Here is a beautiful GIF of our note-taking app (just to give you an idea):
During this time we noticed a problem with the organization of our mob programming sessions. We had too many attendees and this didn’t allow everyone to participate. Having so many navigators turned some navigators into observers. Observing the session without actively participating, therefore without reaping the benefits the meeting was organized to provide. The learning aspect of these sessions was more important than in other sessions, as here we were learning to use new tools we’d soon need to work with and use in production. As a fix for this we decided to split up into two groups, each group moderated by a senior engineer. At the end of the meeting the groups would meet and present their solutions. In this case smaller groups allowed for more focused learning and better engagement from all team members. Unlike the mob documenting sessions there wasn’t a need to be in sync with each other throughout the entire meeting because the primary goal here was not to produce an artifact but to encourage participation and foster learning. Meeting all together at the end for ten minutes was enough to align everyone on what was achieved that session.
These sessions in particular were crucial because as stated earlier they not only helped us all learn new tools, but they acted as a team building activity for two frontend teams that now would need to merge into one. We got an early glimpse of how great it would be to learn and work together.
Improving Developer Experience With Danger JS
Instead of exclusively focusing on learning, mob programming sessions can in parallel be used to work on projects that increase everyday developer experience within the team. With these goals in mind we held a string of sessions where we added Danger JS to our codebase. As a result we now have a useful bot that comments informative messages for all our pull requests (PRs). For example the bot comments regarding which applications are affected by the changes and also comments regarding the size of the PR (we strongly discourage PRs that go near or over 1000 changed lines and/or 100 changed files). Here’s a message generated by Danger from the last PR I opened while writing this section of the article:
Danger also does other stuff like allowing us to enforce that a PR must have an assignee.
We make heavy use of functional programming in our codebase, currently we are using the fp-ts library to support us in writing code within the functional programming paradigm in TypeScript. Unfortunately fp-ts’s documentation is minimalistic and many of its base concepts are inspired by other functional programming languages, and are rooted in mathematics, all of which is taken for granted by the library’s design and documentation. This gives fp-ts a very high learning curve. In fact, while all frontend engineers in our team can effectively use fp-ts for basic tasks, only two of our most senior and technical engineers are experts in it. For this reason while adding Danger to our codebase we also took the opportunity to code making heavy use of fp-ts, so that we could learn from those that were better at using it.
While there was a learning aspect in these sessions, centered around functional programming and Danger, the more important highlight was how we built something that still today provides us with an improved developer experience. We also had the chance to discuss best practices such as:
- What the definition of a small vs. large PR is.
- Why more, smaller PRs are better than fewer, larger PRs.
- Thinking about which applications will be impacted by a PR.
- Having an assignee for a PR be a blocking requirement for merging the PR.
Introducing a New Challenge With Game Development
As you’ve seen throughout the article, we’ve tackled many different projects. However, around February of 2024 we noticed that interest around our Mob Programming sessions was starting to fade. In particular we noticed that: attendance was low (the meeting is not mandatory), working on a specific technology (such as using fp-ts) discouraged those who were not as confident with it from speaking up, and among those that participated it was always the same people who talked and the same people who remained silent. We weren’t working on a particular project and defaulted to the common coding problems I mentioned at the beginning of the article. We were in need of a new project to work on, something to generate excitement, something we’d never done before…
While brainstorming ideas in a meeting I half-jokingly suggested making a video game. But what seemed far fetched at first actually had a wealth of potential benefits. We eventually decided it was an idea worth pursuing and so we soon started new mob programming sessions and made a Snake game! Given that everyone in our team is familiar with Web development, we chose to implement the game to run on the Web using the Phaser game engine.
As you can see, we got off to a bit of a rough start but made progress:
Since almost none of us had made a game before, this project leveled the playing field in terms of expertise. Even the most senior engineers had to ask questions and look at documentation to figure out how to implement the simplest feature. On the other hand since almost everyone knew how the game works, we all had the same vision and could easily discuss what to implement and how to implement it. We also got the chance to code using a completely different paradigm. Many of us hadn’t seen Object-oriented programming in years, so this experience also served as a refresher.
Conclusion
In summary, mob programming has proven to be an invaluable learning and team building tool in our engineering team. By adapting the format to meet the evolving needs of our Chapter, we’ve been able to tackle a variety of projects that have enhanced our skills, improved our processes, bettered our development experience, and strengthened our collaboration.
However, this approach comes with its own challenges. In particular for us: maintaining participation and interaction from everyone throughout the meeting, choosing the right project to work on given the current needs of the Chapter, and keeping a regular schedule amidst crucial product development cycles.
Nevertheless, if we had individually tried embarking on any of the projects in this article alone, the chances of having completed the project would have been much lower and the learning and team building related benefits would have gone to waste. Therefore whether we’re documenting complex practices, learning new technologies, or simply experimenting with something fun like game development, the flexibility of mob programming allows us to achieve much more together than we could individually. I hope this article has given you insight into how you might leverage mob programming in your own team, and we're all curious to hear how you decide to use this approach!