Developing tools for developers
It’s been a few months since I moved to the iOS Core team at SoundCloud. The team is responsible for providing other developers with the tools that they need to develop features for users. We could say that our users are the developers. We are responsible for designing, implementing and maintaining the tools that allow them to interact with core services like the storage and the API. Although what we do at the end is writing code, there are a lot of things that change in comparison with coding features for users. It took me time to adopt the new mindset, and I keep learning new things as I work with my colleagues iterating over the processes and the solutions that we’re designing. In this short journey, I’ve discovered a lot of things, working with other teams, and with people inside the team. In this post, I’ll share some of these learnings.
Developers love to have fun. If you don't provide your team with a challenging environment, they might lose all the motivation that they had for the project and start working on side projects. One of the reasons why people start working on side projects is because their full-time job doesn’t allow them to experiment and try out new things. Make sure you as a team, or your company work on providing the team with that space. Give them the playground that they're asking for and make them feel like children inside the project.
One of the projects that we’re currently working on at SoundCloud is the “app modularization”. Developers can enjoy writing pure Swift without dealing with Objective-C interoperability. Moreover, since these modules are reusable, they can try out the interfaces from Playgrounds, or experiment with other targets and platforms.
Don’t force teams to do the things in a particular manner. For example, if you expose a reactive interface from the tools you limit them to follow the same paradigm. What if the developer is not familiar with it? What if that paradigm is not the appropriate one for the developer use case?. Offer them foundational interfaces and let them decide about the patterns that make them most productive.
With the app modularization, we’re revisiting the interfaces of our networking and storage layers. The old ones exposed reactive observables. Reactive programming ended up everywhere. It also slowed down the onboarding since we had to onboard people in a new paradigm they weren’t familiar with.
But if developers have freedom, does that mean that they could end up misusing the tools? It could happen, but thankfully you can prevent it by designing restrictive interfaces. You have the modifier
final for classes and methods, and the access levels to decide whether something should be exposed or shouldn’t. If a developer needs something that a tool doesn’t provide it’ll open a discussion, feature-request like, where developers will discuss how the new feature fits into the tool. GitHub issues are very handy for that, in the same way, users request/propose features using social networks, developers can request/propose features/enhancements using the issues of the repository where the tools are. It’s very important that your team encourages communication. We are developers, and to achieve X we know we can take many paths to get it done, no matter if any of them implies workarounding any of the existing tools (for example, by doing some reverse engineering). If all developers start doing it, we’ll end up with solutions that are supposed to solve problems that are only solving by being workarounded. In that regards, it’s very important that you actively review PRs and how they use core solutions.
Work following the lean principle as a startup would do with its product:
- Identify the problem, collect as much info as possible, see if other teams are also affected and define your success criteria.
- Come up with a first iteration of the solution, merge it to master and pair on the new solution with the teams.
- Evaluate the success criteria. If it’s not satisfied, work on a new iteration of the solution until you get something that solves that works for all the interested teams.
A solution that works today might not work in a few months. In this, so dynamic ecosystem, many things can happen. In that regards, it’s crucial to define your team KPIs for your work. You could revisit these KPIs from time to time to make sure you are aligned with them. One important KPI could be the teams’ performance: How much time do they spend implementing a new request for the API? How many classes do they need for that? Do they spend a lot of time testing? Don’t expect these KPIs to be easy to quantify. If you work on a feature for a user, you can report events to analytics providers and see the impact that your new feature has on the users. However, If you work on a core solution that is supposed to improve the team performance how do you measure that? One thing that helps a lot is offering feedback channels. It can be a pair-programming session, a meeting, or a backlog of issues in a repository. Via these feedback channels, you know if your solution achieves what it’s supposed to achieve. You should be very open to feedback. Most of the times you’ll have to encourage being transparent. When there’s a developer’s effort in the component, people stay away from giving feedback. Why so? Because they think that by giving you feedback might imply that you have to keep working on the solution. And that’s totally fine; that’s part of the iteration process of coming up with the solution. Listen actively; it’ll help you to identify when something is not working. Developers will thank you when you help them make their daily work easier.
Working as a core engineer and being able to take decisions about the project architecture allows you to influence other areas of the team. An area that we’ve also been able to influence is the on-boarding of newcomers. When a project gets bigger, the learning curve that they have to go through before they get into speed gets higher. That’s a bit frustrating for them. They have to learn about a lot of components, paradigms, tools, and it can take weeks or months. What if they were able to influence the code base since the first day?. Thanks to our modularization project we’ve been able to split the cake into small manageable pieces that include their on-boarding (for example using Playgrounds in Xcode or an example app). Developers can get on-boarded in any particular area, and when they became interested in other, they can just go through the on-boarding of that area to get familiar with it.
Do you work on tools for other teams and would like to share them here? I’d like to hear about them. Do not hesitate to share them using the comments below or reach out to me via Twitter, @pepibumur, or email, [email protected]
Would you like to work with the SoundCloud iOS in a very challenging and exciting environment? SoundCloud is currently looking for iOS Engineers, check out the positions page for engineering to know about the open positions.