DEV Community

Cover image for The Features I Killed to Ship The 80 Percent App in 4 Weeks
Malawige Inusha Thathsara Gunasekara
Malawige Inusha Thathsara Gunasekara

Posted on • Originally published at inusha-gunasekara.hashnode.dev

The Features I Killed to Ship The 80 Percent App in 4 Weeks

I almost fell into a trap believing that "more features" equals a "better product." When I started building The 80%, an assistant tool which helps students to keep track of their attendance, medicals and GPA. I had a strict four-week deadline to ship a production-ready attendance tracker. I quickly realized that if I tried to build everything I wanted, I would never ship what the user needed. Then I remembered what Elon Musk said, "The Best Part is No Part." I didn't just cut features to save time; I cut them to save the architecture from unnecessary complexity.

Here are the five worth-mentioning features I killed in The 80%.

1. The Backup Server Trap

I wasted the first few days being obsessed with 100% uptime. I wanted to build a secondary failover server just in case Firebase went down. I realized I was solving an imaginary problem. Firebase has 99.99% uptime, while the probability of my users having poor campus Wi-Fi is high. The real risk wasn't Google servers failing. It was the connection dropping between the classroom and the cloud. I abandoned the backup server entirely and embraced an Offline-First Architecture using Hive. By treating the user's device as the primary data source, the app works perfectly regardless of server status, I learned that I shouldn't build complex distributed systems when a local database solves the actual problem.

2. The Medical Cloud Storage Nightmare

I planned to add a feature allowing students to upload photos of their medical certificates to the cloud so they would never lose them. But as I designed it, two major problems appeared: the extreme cost of storing images for thousands of users on the Firebase Free Tier, and the liability of holding Personally Identifiable Information (PII). If I held medical records, I was responsible for protecting them from data breaches. As a student developer, I didn't want the risk of a data breach hanging over my head. To solve this, I built the "The Local Wallet." within the app itself. Instead of uploading files, the app simply saves the images in the device's local sandbox and stores a link to the file path. The data stays 100% on the user's phone, resulting in zero cloud costs and zero privacy liability. I learned that the most secure data is the data you never collect.

3. The "Automated Email" Fantasy

I wanted to build a productivity hack where the app would automatically send official emails from the student's university account using SMTP or OAuth. It sounded like a great productivity hack until I looked at the technical reality. University firewalls and Multi-Factor Authentication (MFA) makes this feature hard to implement. Making it work I had two bad choices.

  1. Requesting Credentials from the User: Asking users for their university passwords which leads to a a massive security violation that looks exactly like phishing. or
  2. Enterprise Verification: I would have to navigate the university's bureaucracy to get official OAuth approval. I avoided this method in order to reduce the complexity of the app. I killed this automation entirely and stuck with the traditional email flow. The app automatically opens the default email app, then the user can send the drafted email with the medical report. I learned two major lessons here. First one is "Trust is harder to build than a feature." And as developers we shouldn't compromise security for a "cool" automation.

4. All University Supported Grading System

I had a plan to create a database containing the grading scales for all major universities all around the world to automate the GPA calculation process. But I quickly realized that this needs constant maintainability, which I don't have time to do as a undergraduate. It would require weeks of manual data entry and maintenance, and if a university changed their grading policy, my app would be instantly outdated. It simply wasn't worth the effort for my app. Instead, I built a feature that allows the user to configure their own grading scale. This taught me that when shipping, flexibility is often better than hard-coded perfection.

5. Sync Custom Profile Picture Across Devices

I wanted users to be able to pick a photo from their gallery and have that custom profile picture sync across all their devices via Firebase. This led me to the "Cost" problem again. I would need a paid Firebase plan to store these custom images, or I would have to bloat the database by storing base64 strings, which requires unnecessary processing power and time. I compromised by removing the ability to upload custom photos and instead provided a set of high-quality, pre-defined 3D avatars. I only sync the Avatar ID (a simple integer) across devices, keeping the data transfer minimal. This was a valuable lesson in distinguishing between what is needed (identifying users) versus what is wanted (full customizability).

Conclusion

It is easy to add features. It is hard to remove them. By killing these features, I didn't just save time; I built a product that is faster, cheaper to run, and more secure. I learned that my job isn't to build the most complex version of an idea, but to ship the version that actually works. The 80% proved to me that sometimes, the best code is the code you delete.

Top comments (0)