How did I build cropping of receipts in the mobile app?

Hey there, I’m Yash Solanki. I graduated in 2021 (Courtesy pandemic), joined Fyle, and have since been working in the mobile app team.

PS - I’m no novelist or wordsmith; this happens to be my first blog post, so if you find any obvious grammatical errors, please let go of your OCD or buy me a Grammarly premium subscription😛

Why bother cropping receipts?

  • When submitting an expense, the receipt image might be zoomed out and have irrelevant objects in the background. Wouldn't it be great to modify the existing image instead of clicking a new one, right?
  • If the image has just the receipt without any unwanted background, even the approver/manager does not have to zoom in to see the receipt.
  • A cropped image will help extract data more accurately, and you won’t have to do any manual work.

How did it start?

We at Fyle strive to follow the Lean philosophy and it means focusing on what is necessary and delivering the Minimum Viable Product(MVP) to your customers ASAP. This quicker delivery helps us identify if we’re doing the right thing.

A lean business model is a business strategy that strives to eliminate waste in products and processes while satisfying customer wants.
(Translation: If the customer says build it, we have to build it!)

We decided to build a rudimentary version of the crop receipt feature without having any UI designs(Design work happening in parallel). Like Abhishek always says:

Do not reinvent the wheel.

We explored multiple solutions for image cropping in Ionic and Angular:

Based on the performance, popularity, release frequency and Github issues, we narrowed it down to Ngx Image Cropper.

The development phase (where the magic happens!)

One of the major pain points in mobile app development is maintaining compatibility across all devices - Android and iOS with different resolutions and OS versions.

If some of our customers are running an older iOS version, and if we introduce a new dependency that does not support a particular OS version, we would break the internet! We didn’t want our app to crash for any of our customers. Similarly, if someone is using a beta release of iOS, then all our dependencies should be updated to support that too!

We quickly built a POC (proof of concept) and tested our app on multiple devices. After all the testing, Voila! The change was out in the wild. As bugs happen with all releases, it wasn't any different this time
Bugs are a part of any feature

I was patting myself for pushing out a feature so quickly. After a few days of the release, I was curious to check the usage data in Mixpanel (Yeah, as I said, we’re a pretty data-driven company) there was Zero usage, Zip, Nada and I was like
What? No usage? How come?

When a senior developer warns us against using any data type in Typescript, well you should take them seriously. So, I misspelt an object key and so no events were triggered and thanks to any, Typescript did not report any error :(

The fix was relatively straightforward, and once the new release went out, we started getting decent usage and then Madhav from the Data extraction team found some more issues in the service logs!

At this point, my manager must have been thinking

Translation: Dude, wtf is this?

And I was thinking

Translation: Why doesn't this pain end?

Long story short, the image cropper, by default, was converting the cropped image to png format, which was throwing a few errors while decoding the base64 string. This, in turn, broke data extraction. We quickly fixed it and started seeing very high usage!

You might be thinking; all this is good talk, show me the numbers, here you go:

Usage of Crop Receipts
  • In the last 30 days, more than 20% of all our users have used this feature.
  • This week, there has been a whopping 4-5x increase in usage compared to a few weeks ago.
  • As of date, more than 16% of all the receipts submitted using the mobile app use cropping.

What did I learn?

  • Read the damn documentation.
  • Test your changes thoroughly and make sure it doesn’t break any other service, even if it is remotely related to your change.
  • Before using a new plugin/dependency in your app, always do a small POC for verifying its compatibility.
  • When releasing a new feature, always track its usage.
  • Keep an eye out for any errors or warnings in production related to your change.
And did I tell you I was an intern when I did this

A massive shoutout to the entire mobile app team, Aiyush Dhar and Abhishek, for guiding me and giving valuable feedback throughout!

Yash Solanki

More of our stories from

Demystifying Class Variables In Python

Understanding class variables in python

Interview Experience: Backend Engineering Internship at Fyle

Wanna know the secret to crack backend engineering interviews? Learn them here and intern at Fyle!

The curse of being a Senior Engineer, how to deal with timelines, frustrations, etc

Being a good developer is 50% skill and 50% emotional support; here's my secret to balancing both at the right amount!

How did I build cropping of receipts in the mobile app?

Follow Yash's journey of what it takes to reduce manual work for our customers when receipts come in all shapes and sizes!

How did we increase Data Extraction accuracy by a whopping ~50%?

Wanna know the secret of data extraction, the complex machine learning models we use, the experiments we did? Read on...

The not so secret sauce of my work

From chaos to clarity, follow Chethan's not so secret sauce to excelling at work!

From Zero to Hero: The Policy Tests Journey!

The story of policy tests at Fyle

How Fyle changed my life from a naive intern to a confident Engineering Lead

A blogpost that documents Shwetabh's journey at Fyle.

Vikas Prasad @ Fyle

This document is a user guide to Vikas at work.

Gokul K's README

This document is a user guide to Gokul at work.


All Topics