Today, more and more companies are adopting a fully remote policy. Along with the advantages come a few new challenges. Among them the one we’re going to focus in this article: how to organize a team without ever meeting them.
Swapcard was founded in Paris and started small with the entire team being in Paris at the time. Now, the company is more than 200 people strong, but only around 30 people still work from the Paris office. The rest of the people are scattered throughout the world. Swapcard’s culture is 100% directed at how best to integrate each and every one of its employees and they’re doing a terrific job, but it’s still up to each department to organize collaboration in their ranks.
The frontend team (which I’m a happy member of) has been experimenting with various methods and processes, and this article aims at detailing how those tools are making our everyday collaboration and growth a success. I will specifically be talking about where the information exists and how it’s organized; how rules and practices are discussed and evolve; and how we enforce their usage.
Tools in use
To achieve the processes we have, we’re using tools most companies are familiar with, I’m listing here those that will be mentioned further into the article:
Notion: It’s the knowledge base of the company. We use it for all kinds of company-wide information and rules such as internal rules, org charts, processes, and contacts. We also use it for local things like the Paris office’s wifi and trash sorting rules. Each department uses it for their own internal documentation, write down all of their processes, rules, meetings reports, etc. Basically, everything that anybody could have a question about at any point.
Slack: It’s used company-wide for both important company communication and everyday professional/personal chats. We created several channels each with a very specific purposes so no channel is cluttered and information is easily findable.
Jira: It’s used by all the engineering department for project management. We have boards for every team but also shared ones that I will talk more about further down.
Agile methodology: Our project management framework doesn’t follow the SCRUM guidelines to the letter but is still very close to it. This means we have all the scrum ceremonies like daily stand-ups, sprint plannings, retrospective meetings, and others.
Team organization: It is based on the Spotify model and aims to scale the agile approach and keep an innovative, creative startup vibe. The product and the tech team are organized in:
- Squads → team that is capable to deliver full features by itself.
- Chapters → is a cross-squad, cross-tribe group of developers for the same technology.
- Tribes → it's a group of squads that is centered around the same goal.
When sharing physical offices with your team you get organically onboarded by the people, day by day. Every process gets explained, observed, repeated and assisted by someone until they’re assimilated. If something changes, the transition happens the same way since everybody around us transitions to it in the same physical space.
When working remotely there is no such natural flow of information happening; so all the information needs to be written down in a centralized place and thoroughly detailed, a lot like documentation.
Before our developers can even contribute to the codebase, we need them to be able to run our various apps locally. So, we created pages to detail how they should be installed, how the configuration files should be added and what they should contain. This may seem trivial but as our tools and libraries evolve, someone may add an item to an apps configuration – which would make running it fail for everybody without an up-to-date config file. So all additions are added to the documentation, and the change is notified in the appropriate Slack channel so everyone can update their setup.
In our team anybody can do releases, be it in the dev, staging or prod environment. So we need to document each of those processes for each repository detailing each step to make sure no one breaks anything. Those steps also include warning about releases in Slack and giving timely status updates. This ensures everyone is aware of what’s happening at each moment so they can decide if they may proceed with their tasks or not.
To help keep a good consistency in our codebases, we also have preferred ways of writing different kinds of code blocks and patterns to implement. For instance we have guidelines about how to handle fetching, rendering loading states, rendering errors, etc. We also have guidelines about how we should generate mock data, write stories (we use Storybook extensively), and how they should be reused in our tests. Those come with numerous code examples, edge cases covering, warnings and explanations about why we’re preferring what pattern.
Those pages, obviously, are always kept up to date as our guidelines change.
Do’s and don’ts
Finally, for all guidelines that do not fit in a broader category we have the do’s and don’ts section. There we list all preferences regarding general code styling and good practices such as syntax specifics and naming.
The do’s and don’ts section is our reference in case of doubts or "conflicts" during discussions or PR review, and the items in it are translated into linter rules when applicable (see “enforcing the rules” section).
All those guidelines ensure code written by developers from different squads will be as homogeneous as possible. It has numerous advantages: it eases PR reviews, makes getting acquainted with unfamiliar parts of the codebase way easier, and it makes sure everybody uses code that performs better and is less bug-prone.
Now that all this information exists we need to make it known by developers.
The process of integrating a new person into the company and bringing them up to speed with the current state of the codebase and the practices is a great occasion to map all the knowledge we created earlier. Since the company grew very quickly over the course of 2020 and 2021 (+150 employees) we put in place a thorough onboarding guide for greeting each new member in the team. The guide walks them through all our documentation so they learn about our ways and know where to find information they need.
This guide can also serve as a reference for existing employees to find the content they’re looking for.
Most developer teams already use ticket-based frameworks for tracking their tasks’ statuses so we figured setting up a kanban board for tracking specific parts of the onboarding process would feel natural to most recruits. Right now we’re using it only for the environment setup, but it could be done for the rest of the onboarding too. The blocks redirect to the aforementioned pages detailing all the steps to complete – so that anybody onboarding or starting from a fresh setup can be ready in less than a day.
Discussion, growth and evolution
At Swapcard, our developer base is divided into squads. Each squad works on topics or apps whose specifics are not discussed with other squads on a daily basis. If each squad handled their subjects independently without ever discussing them with the rest of the team, our practices and procedures would grow apart. This could result in a codebase that is complicated to maintain and conflicting approaches to PR reviews. This is why we created a weekly meeting for the entire team, called the chapter meeting.
I would say that those meetings are the backbone of our team’s communication and growth. They happen every week on the same day and at the same time and usually last between 45 and 90 minutes.
We have a dedicated section on Notion for them, in which can be found the reports of all previous meetings, the topics discussed, the conclusions and the actions that were taken. Before each meeting a page is available in this section called “Next chapter meeting”. There, any developer can go and create a topic using the template we put in place and describe the topic in as much details as needed for everyone to understand it.
All kinds of subjects can be invoked during those meetings. Examples include:
- “I had this problem and solved it this way, what do you think?”
- “I've been seeing different ways to do the same thing around the codebase, what do you think would be the best approach?”
- “We're doing this but we should stop because X and Y”
- “I've seen this new lib and think we should use it, what are your thoughts?”
- “I saw this other pattern somewhere, what about implementing it in our codebase?”
- DX improvement ideas (scripts, processes, tools, etc.)
- Ideas for new projects inside the company
Topics are debated at length and in depth with references to benchmarks, studies and articles when possible to document each opinion and take the best decision for the team. We often learn something in those and end the meeting with interesting reading lists.
Most of the time, those discussions result in new or updated guidelines, processes or projects. If we decide to bump some packages (like Storybook, React or Next for instance) it unlocks new patterns for us to discuss. So if we bump Storybook, we’re going to create one or more do’s and don’ts items, probably refresh the documentation page about how we write code/tests/stories and finally create tickets in our shared Jira board to refactor the existing code so we always keep our codebase aligned with our rules.
The shared board is a Jira board shared across the entire chapter, unlike the squad-specific ones that are private to each squad. All tickets discussed during the chapter meeting would be created there, then discussed again if needed to agree on specs. Once a ticket is ready to be assigned, people can either freely take it or request during quarter meetings to work on it. At the beginning of each quarter we usually go over the “ready tickets” backlog and try to assign them to people. This allows everyone to know which chapter subject to focus on during the months to come. As with a regular agile board, progress is tracked on the tickets and they eventually finish in the “Done” column.
10% of sprint velocity for chapter tickets
Of course, since the shared board tickets are not directly linked to a squad, they’re not accounted for in the product roadmap and are not naturally part of future sprint backlogs.
To ensure developers can continuously work on chapter tickets, the company has agreed to allocate around 15% of each sprint’s velocity to them. Because really, reducing the tech debt improves the overall developer experience, speeding up development cycles and helping reducing the introduction of new bugs.
Swapcard’s top management very well understood the mid and long-term benefits of continuously fighting tech debt, and strongly encourages us to take advantage of those 10%.
Enforcing the rules
Now that we’ve made sure the rules are well-structured and accessible – and that we have a process to challenge them and make them evolve – we need to make sure people actually abide by them.
Centralized lint config
Right now we have apps in different repositories (although we’re currently migrating them into a monorepo), and we also have numerous separate internal packages we’re using in our different apps. In order to maintain consistency and to enforce our code style rules we created a shared lint config used everywhere in our codebase. This ensures all code from everywhere remains up to date with our evolving standards.
Mandatory and scrupulous PR reviews
Try to enforce that at least once a day all of your pending PR reviews are pruned.
PRs are very important and have at least two purposes:
- The first one is obviously reviewing the code that goes into production to make sure no bugs or unwanted side-effects are introduced. This is also the opportunity to make sure the new code follows all our guidelines!💡
- The second one is more at the advantage of the reviewer. It allows them to remain up to date with what happens in the codebase, witness what solutions people come up with to problems they may encounter themselves, and potentially spark conversations that might result in chapter topics.
We’ve also taken advantage of Github’s possibility to create PR templates to enforce some of the good practices we’ve agreed upon. Those templates include various things such as our PR title being properly formatted; the PR having added or updated stories and tests to account for the code changes; and making sure the changes meet our accessibility standards. Those templates are an extension of our rules. They also make sure our guidelines are remembered and applied.
Additionally, the PR template makes sure the PR creator has made their changes available on the dev environment, to ensure both QA and reviewers can test the feature. For reviewers, mandatory testing on the dev environment is highly beneficial: it helps better prevent regressions or bugs, but it also drastically increases each contributor’s product knowledge and meta skills.
In order for a PR to be ready to merge, it requires the approval of at least two reviewers and must have a pass on all its pipelines. The pipelines basically test if the code is buildable – there are no typing issues, unit tests pass and e2e tests pass.
Usage of Slack channels
Last but not least, we’re using Slack channels to separate various communication contexts. We have an all-purpose channel, but also a few others dedicated to very specific usage:
- Private: for everyday discussions, but also general ones about our apps, weird errors reports, questions, etc.
- Releases: whenever someone starts a release process, to inform about the start, progression, possible issues and finish of a release, in real time (with updating emoji for statuses ⏳/⚙️/✅). This is a direct application of how our release processes are structured and described in Notion.
- War-room: created as needed when an urgent bug is reported, with only the needed members and deleted when the bug is solved. Our SLA demands very quick resolution times of us and those rooms should always be treated with top priority.
Personally, the biggest advantages of working in a company instead of freelancing are the people, the discussions, and the ability to grow when working with talented people. But, in a fully remote company you might not really benefit from those advantages if the communication and organization are not handled properly. Even worse, you might end-up feeling a bit lonely and isolated.
Our processes are obviously not perfect and we’re continuously working on improving them, but I can say that so far they’ve been bringing to the table everything I expect to find in terms of growth, thinking and discussions when working with people.