Spotify recently published a detailed account of its journey towards a unified codebase for its web and desktop clients. At the end of 2018, Spotify's team was the owner of a recently built web player, as well as a separate, rich, full-featured desktop client. Due to having to implement many features twice, Spotify's engineers were not shipping new features at the pace they wanted. Now Spotify created one maintainable codebase for both, resulting in an improved development cadence.
Spotify had four main goals with which they evaluated the project's success. The first was reusability. Spotify reused the same code in multiple clients, which allowed them to write the code once and reap the benefits in various places. The second was unification. The project permitted Spotify to unify the user experience and visual design across platforms and make it consistent with the rest of the Spotify ecosystem.
The third goal was speed. The new architecture made UI coding simpler and easier to understand as developers. As a result, their development speed increased. The last goal was user satisfaction. Spotify continuously conducts user tests to meet the desktop and web player users' needs.
Spotify's team explains their strategy for approaching the code convergence project:
We knew we were embarking on a long-term project, so our biggest priority was to de-risk delivery and avoid trapping ourselves into a big bang rewrite. We settled on a bold solution: focus on iterating on top of the existing Web Player codebase until it reached a Desktop-grade feature set. Since our Web Player is continuously deployed, we could ship and test with real users every change made towards our final goal.
The engineers designed the previous desktop client to foster autonomy, allowing multiple teams to own the development and maintenance of the features. It was a native Windows and Mac application that used the Chromium Embedded Framework (CEF) to display a web-based user interface. Every "page" in the client was built as a standalone "app" to run inside its iframe.
The previous architecture of the desktop client
Source: https://engineering.atspotify.com/2021/04/07/building-the-future-of-our-desktop-apps/
The team decided to base the unified client on their web player's codebase, with CEF hosting it on the desktop. They explain the reasoning for this move:
The Web Player's codebase was considered a much more solid foundation to build upon. It allowed us to develop new features quickly. It was developed with the web in mind, meaning it was small in size, more performant, and worked with various browsers. The client was delivered continuously, allowing changes to get to users almost immediately.
However, this decision came at a cost. The web player was tightly coupled to Spotify's web servers, the playback system worked differently, and even authentication required a different implementation using native APIs. Spotify engineers describe the solution:
To keep the UI platform agnostic, we built TypeScript Platform APIs that would abstract the different sources of data and different playback stacks and provide helpful information to the user interface about what functionality was available to it. We also rewrote the whole client in TypeScript along the way, as we were rebuilding the experience bit by bit.
The architecture of the new web player (left) and desktop (right) clients
Source: https://engineering.atspotify.com/2021/04/07/building-the-future-of-our-desktop-apps/
To reduce risk, Spotify created a small "virtual team" to begin the very first engineering experiments and determine if the web player can be placed in a desktop container at all. The team's work concluded successfully after three months, and the project began soon after that. The fact that Spotify engineers previously co-located both codebases in the same monorepo was key to facilitating this task.