- read

Behind The Scenes: Crafting Razorpay’s new mobile app

Chaitanya Deorukhkar 24

Engineering Culture

You’ll often hear people say that while switching a job, the most important factor to consider is the engineering culture of the company. What does engineering culture mean though? Who creates it? Who has the ability to define and mould it?

In our opinion, engineering culture is a healthy balance of the team’s beliefs, practices, and behaviours. This leads to a good work-life balance, opens up growth opportunities, and provides job satisfaction.

The birth of a company’s engineering culture happens in the early stages of the company. The founders and the early team members are responsible for creating this culture intentionally or unintentionally.

As engineers, we generally rely on our managers and leaders to spot areas of improvement in our engineering practices and we hope that someone will help improve it but what if we don’t just rely on others? As engineers should we only fix bugs in our code and not in our engineering culture?

Baking culture along with the product

Engineers building and evolving the culture sounds like a fairy tale but let us tell you how our engineers started building it when we formed the mobile app team.

Early on things were blurry in terms of engineering. We started by building a team of a handful of engineers to figure out what needs to be done. In our early discussions about building the mobile app, we as a team knew that we don’t just want to build a product and ship it, we wanted to do it “the right way”. We did not have a checklist for “the right way” but it was our passion to build a product with engineering practices that we all believed were ideal.

We set some high-level outcomes we wanted to achieve

  1. Select a tech stack that we’d love to work with and has clearly visible benefits that would be easy to scale up in the future.
  2. In order to ensure high quality, we wanted to leverage tools that enforce us to achieve and persist it.
  3. Have a healthy work-life balance and avoid burnout.

Once we identified the tech stack and the tools we’d use to make our lives easier, it was time to communicate in detail why we chose them. It’s not always easy to choose a tech stack that everyone agrees with. This is why it became crucial to justify our choices. We wrote a tech spec that detailed out how we plan to build the mobile app. Each framework and tool had a clear explanation of why we chose it and how it would benefit our app’s ecosystem without any biases along with clear trade-offs.

The Tech Stack

Our tech stack and the set of tools were made up of React Native, TypeScript, GraphQL, In-house Design System, Bitrise, Codepush, Firebase, Sentry & Apollo Studio.

Choosing the tech stack and leading the efforts to communicate and convince the org for the same was a defining moment for our team’s culture. It instilled the values of ownership and autonomy in the team. Once we had everyone on board with the choices made, we decided to set up the entire app’s base and the infrastructure before we start building features. This enabled us to create a strong base for the product.

Even before the first feature was built, our app had a proper CI/CD in place which took care of running our suite of unit and end-to-end tests. We were also able to push our app to production using Bitrise with just one click. Our app would be tested, built, and distributed to the Google Play Store, Apple App Store and send out OTA updates with Codepush if needed for older versions.

One of the big wins of having this base setup for automatically testing and deploying our apps was how it enabled us to push features and bug fixes to our design and product teams faster where we were just focussing on building the product as the rest of the infrastructure was already automated. It was like we were dogfooding our own infrastructure while building the app.

All of this led to building a good engineering culture within our team where we were able to build things “the right way”. But to have a good work culture you need more than just the right set of tools. We leveraged a lot of potential opportunities in our day-to-day work and fixed them to boost our productivity.

The Practices

Here are some of the practices we adopted that helped us organise our way of working and improve our productivity.

Quicker sprint planning

Before we started our sprint planning with a wider team of managers and designers, our engineers would be ready with a list of sprint tasks that they will be picking up individually along with a time estimate for each task. This ensured that the managers’ role was to go through our lists to make sure we’re on the right path and suggest some minor changes to the plan if required.

This way we were able to complete our sprint planning within 30 minutes. Yeah! Can you imagine just 30 minutes?

An added benefit was that our engineers had the autonomy to lead the roadmap of how they want to build out the product while simply aligning with the rest of the stakeholders.

Optimised estimations

Estimating is always a difficult task and we learned this as we built our app. We realised that we need to account for time in our sprints for writing test cases, doing PR reviews, and leaving some buffer space for ad hoc tasks. Over time, our estimations were very accurate and that aided us to chase sprint burndowns.

Snapshot of Google Sheets where we account for writing tests as well as building features in our sprints

Sprint burndowns

Sprint burndowns are total tasks picked up in the sprint to total tasks actually finished. We made sure that we chased sprint burndowns and completed all of the tasks we picked up. This kept us on track sprint after sprint and we were able to launch our app on time.

Snashot of a really good sprint burndown chart

Weekly releases

We established a culture of weekly releases by blocking our calendars every Thursday to deploy new features and bug fixes we’ve been working on the week before. This enabled us to get faster feedback from our product and design teams.

Sansphot of a recurring calendar invite for releasing the app internally every week

Publishing changelog

With each release, we’d write up a clear and concise changelog and publish it to our internal teams so that they know exactly what’s been baked into the new version and what they can try out to give us feedback.

Snapshot of a concise changelog that highlights specific changes in a release

Daily catchups & standups

We organised daily catchups amongst the engineers to discuss our progress, the day’s plan, and if we’re facing any blockers that need to be resolved. We tightly scoped this catchup to 15 minutes so that we don’t waste too much time on endless meetings. We also moved our standups to slack where we would individually post updates about our work to keep other stakeholders in the loop and highlight any blockers or dependencies.

Timely pull request reviews

We set up a Slack bot that would remind us at 10:30 am every day to do PR reviews. This slot was immediately after our daily catchups so that we would be in the context of what others are working on and review their work on time.

Snapshot of a slack bot reminding the channel for reviewing PRs everyday at 10:30 am

Smaller pull requests

We followed the practice of trunk-based development which means that the work we do needs to get merged into master as soon as possible. This way we would create smaller PRs which would make it much easier to review them. Even when a feature was not ready, parts of it would be in the master hidden behind a feature flag which would be toggled on as soon as the feature was ready.

Bug bashing sessions

We established a culture of blocking an hour each week on a Wednesday, 1 day before our weekly release, where we go through our monitoring services like Sentry, Crashlytics, etc, and triage/fix bugs depending on the severity. If some bug is expected to take longer to fix, we’d simply add it to our next sprint’s plan. This ensured that we were always on top of the bugs introduced in the app and they’d get fixed much sooner than later.

Distributed responsibilities

To make our ownership of different aspects of the app development more concrete, we started distributing responsibilities amongst the team.

One person took ownership of organising our bug bashing session and would take care of ensuring that we did these sessions regularly. They would maintain a list of bugs that needed to be fixed and follow up with folks who were responsible for fixing them.

Another person took ownership of deployments. They would ensure that we did our weekly releases on time and communicate changelogs with the stakeholders. They’d also be responsible for maintaining our CI/CD pipelines and be the point of contact for failures.

Another person would be in charge of running the daily team catchups and sprint planning. They would take care of ensuring that we prepared well for sprint plans and that our sprint remained on track.

These habits ensured that no one person was overworked with a lot of responsibilities and we had POCs for different aspects of our work.

Balancing tech debts and product features

Since the engineers were leading sprint plans, we ensured that we keep a balance of picking up tech debts each sprint and avoid them from piling up. This became a practice of picking up non-product tasks in each sprint and in the end we had both happy product and engineering managers.

Snapshot of a Google sheet showing how we pick up tech debts in our plans alongside product features

Vernacular support

Our value of autonomy enabled us to build a feature without it being a product requirement. We decided to add support for multiple languages in our app from day 1. Although we didn’t officially add support for languages other than English, we built our app in a way that supporting additional languages would mean just adding a translation file for all the words shown on the UI. This meant that whenever we create a new feature on the app, we had to be conscious of not using the words on the UI directly but instead write them via a translator tool (we used react i18next).

Snapshot of our Login UI in Hindi

Monitoring tools

Since we spent a good amount of time making the core foundation of our app strong, we had all the alerts in place which helped us monitor the stability of our app regularly so that we could fix issues even before someone reported them.

Core working hours

We started the practice of blocking our calendars every day for “core working hours” where we’d turn off our slack and email to avoid all the distractions and meetings. This helped dedicate chunks of time to actually write some code without being pulled into some random tasks/meetings.

Pre-launch Jitters

Building a product at this scale is never entirely a smooth ride. We faced a lot of hurdles before we released our app and we were able to learn something valuable from each of them. Most of these hurdles were cross-functional and pushed us to eventually become efficient collaborators.

Engineering x Design

One of the most challenging aspects for our engineers was to create interactions for the bar graphs in the app. We had graphs that looked as intended but the behaviour wasn’t exactly as our designers wanted them to be. As a team, we took the decision to de-prioritise fixing these and take it up post-launch as enhancements. For months before launch, this became a recurring nightmare for our engineers and it was evident that our designers were disappointed too. We could release it as it was but it wouldn’t meet the high standards that our design team had set for us.

A few days before the launch as we were preparing to freeze our code, we decided to do a mini team hackathon. After hours of pair programming as a team of 4 engineers and trying every possible fix we could think of, we finally were able to make it work exactly as our designers expected!

It was the sheer sense of ownership that the team had for the app which made it possible to reach every expectation that was set for us. Happy engineers and happy designers!

Snapshot of the graphs in our app while in debug mode alongside the snapshot of the graphs in production
Colourful debugging

Engineering x Product

A week or so before the launch of our app we realised that as a product, we lacked an important feature that could impact us — Showing a pop-up to our users for rating the app and giving us their feedback. Our ideal way to do this would be to show native store rating dialogues but with the time crunch, we had to build something that does the job. So the whole team of Engineers, Designers, and Product managers got on a call and ironed out how and when we wanted to show this pop-up and build the most minimum viable option for it. An entire feature planned, designed, and kicked off development in one call! Happy engineers and happy product folks!

Snapshot of our app showing a popup to take user feedback and submit a rating as well

Engineering x Engineering

A month before our launch date engineers realised that the number of features planned for the month and the bugs that we need to fix would take up the whole month leaving no buffer time for us to rely on. We knew this could be a challenging task to deliver on the said date and any ad-hoc or unforeseen issues could lead to us not being able to meet the deadline. We had the luxury to push the deadline by a few weeks but we also knew that we didn’t want to deter ourselves from delivering on the date we promised. We took it as a challenge for ourselves to meet the deadline.

Unfortunately, there were ad-hoc and unforeseen issues. Even then we decided to not push our launch back and power through it. This meant giving up all the rules and practices we lived by. We started working extra hours, working over the weekend, calling up each other and cross-functional teams at odd hours. Looking back, we wish we had planned better for the final month but at that moment, we were on a mission to stay true to our promises. Towards the end, we were tired but we met our deadlines and launched the app on the day we promised! Although we did all of this from the comfort of our homes, each one of us wished we were at the office celebrating our accomplishments and the launch!

PS: We took more than enough time to rest and recover after our launch. More on that later.

Reaping The Benefits

Because of all the practices we followed as a team, we gained some of the following benefits.

The beta release

Since we had our weekly releases and a well-established feedback loop, launching the app to a limited set of users outside Razorpay didn’t come like a nightmare for us. We were confident enough to launch it without spending sleepless nights to push it to production (you know what we mean 😉). Releasing it early to our users gave us a lot of insights regarding what we need to build to provide more value to our customers. A lot of usability issues were discovered through this feedback which helped us polish our app for the final release.

Post-release vacation

After the first public release of our app, the entire team took a week-long break from the very next day of our release to relax and celebrate our accomplishment. We were able to take this break since we had invested in the foundation of the app early on which made us confident that there won’t be any major crashes or p0s. Even if there were, we’d be alerted immediately by our monitoring systems. There were no p0s and we rested well for the whole week!

Healthier work environment

Each day would be well structured and we’d know exactly what we’re getting into. This helped us to plan our day better so that we could maintain a good work-life balance.

No burnouts

The team always felt in control throughout the entire period. Thanks to proper planning, practices, and processes, the team stretched a limited number of times in short bursts, and it was always the team’s decision to do so. More importantly, it was fun!

Scale-up seamlessly

We crossed ~35K installs with ~17K monthly active users within 3 months from the launch organically and our entire infrastructure helped us to scale with ease.

Advantages of Design System, GraphQL & React Native

We adopted the mobile app as a pilot project to build with React Native, GraphQL, and a Design System. By showcasing the benefits we got from these on the mobile app, we were able to make a bigger case of using these technologies in more of our frontend projects. Previously where only the mobile app team was working on each of these technologies, we now have dedicated teams to help build our Design System, build a set of tools for frontend infrastructure and scale up our GraphQL.

WFH like a pro 🏠

We did all of this while working from home! Nobody in the team had any previous experience of working remotely but having our engineering practices in place and polishing our collaboration with teams over time, we managed to build something we’re all proud of!

Snapshot of the whole mobile app team on a zoom call

Join Us!

If you liked the work we’ve done, you’ll be more excited by what we have in store next. If you’re looking out for frontend opportunities, we’d love for you to join our team and help us build the future of Razorpay!

Here’s a short glimpse of some of our frontend work

Head to this link and apply right away → Frontend At Razorpay