iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
📱

How I Scaled My Personal App to 400,000 Downloads in 5 Years

に公開
2021/12/06
1件

This article is the 3rd entry for the CyberAgent 22 New Graduate Advent Calendar.

https://adventar.org/calendars/6671

Introduction

Do you engage in personal software development? If so, for how long have you continued to work on a single project? In this article, I will introduce a case study of a personally developed app that I have continuously updated, reaching 400,000 downloads over five years.

About Me

Here is a little bit about the person writing this article:

  • Enrolled in an information technology university.
  • Started working with Java in middle school and began app development (Android) in high school.
  • Since then, I have gained development experience with iOS, Unity, Laravel, Next.js, etc., depending on what I wanted to build at the time.
  • Planning to work as an Android engineer.

The App I Develop

I am developing a learning support app called "Anki Maker" (Memorization Maker).

This app specializes in "creating," "answering," and "sharing" problem sets, aiming to streamline studying for tests and certifications.

Its key differentiators from similar apps include support for multiple problem formats and the ability to start using it immediately without account registration (offline) if you only want to "create" and "answer" problem sets.

Image 1 Image 2 Image 3 Image 4

Android:
https://play.google.com/store/apps/details?id=jp.gr.java_conf.foobar.testmaker.service&hl=ja&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1

iOS:
https://apps.apple.com/jp/app/テスト勉強用アプリ-暗記メーカー/id1201200202?mt=8

Introduction Page (Browser version):
https://ankimaker.com/

Technical Elements

I will introduce the technologies that support "Anki Maker." As development has been ongoing for a long time, it has become a mix of new and old technologies. I am often tempted to rebuild it from scratch periodically.

  • Android

    • Kotlin, Jetpack Compose, Coroutines, LiveData, Databinding, Epoxy, Navigation, Koin, Realm...
  • iOS

    • Swift, SwiftUI, SnapKit, Realm, RxSwift, Combine...
  • Frontend

    • TypeScript, Next.js, Tailwind CSS
  • Backend

    • Firebase
      • Authentication, Storage, Firestore, Cloud Functions, Crashlytics, DynamicLinks
  • Other

    • Bitrise: CI, CD
    • AppFollow: Review management, ASO support
    • RevenueCat: Support for implementing in-app purchases
    • IFTTT: Periodic ego-searching on Twitter
    • Figma: Creating logos and store screenshots
    • Slack: Aggregation of reviews, inquiries, ego-search results, and crash logs

Since it is tedious to jump between various services, I focus on aggregating incoming information into Slack.

Throughout Development

I would like to introduce some things I am glad I did and some I regret while continuing development.

Multiple Motivations

I am the type of person who gets bored easily, so I feel it was a good result that I was able to approach app development with multiple motivations. Specifically, the following elements serve as my motivation for development:

  • I want to streamline my own test study.
  • I want to practice newly learned technologies and tools.
  • I want to increase numbers such as "number of users" and "revenue."

However, one must be careful with the second point; you should think about whether that technology is truly necessary for your app before starting. (e.g., trying to adopt an architecture based on the assumption of large-scale app development, only for the code to end up being redundant, etc.)

Maintenance Costs

Even if you go to the trouble of releasing an app, it is mentally exhausting to keep developing it while continuing to run at a loss. In my app, I develop while keeping the idea of "it should be fine (financially) even if left alone" in mind, so I do not have to worry about maintenance costs. Specifically, I have reduced maintenance costs through the following efforts:

  • Monitoring the transition of advertising revenue from the Android version, and releasing the iOS version at a timing where it seems there will be no issues paying the annual Apple Developer Program fee.
  • Completing basic functions on the client side to keep backend costs down.
    • Only problem sets that users want to share are uploaded to the server, which is highly compatible with usage-based billing.
    • However, this also has the disadvantage that it is difficult to collect user data.
  • Making the app title easy to understand. (Test Study App "Anki Maker")
    • This allows for expected downloads from search traffic without spending money on advertising.
      • Maintaining a high search ranking for "test study," "problem set," and "memorization."
    • In particular, the number of downloads increases significantly during test weeks.
    • This is the strength of tool-type apps. As long as there is a demand in the world to "study," users will discover and download it on their own.
    • Conversely, even if you introduce it to the general public, it is difficult to increase the number of downloads in the short term because if there is no reason to study, there is little opportunity for people to "try it out for now."
Android iOS

...It goes without saying, but I try my best not to neglect bug fixes and OS update support.

Revenue

Having discussed the cost side of things, I will now talk about the revenue side. The main sources of income for "Anki Maker" are advertising revenue and ad removal (in-app purchase), with advertising revenue being the primary source. Initially, revenue was negligible, but as the number of users grew steadily, after five years, I am now earning about as much as a part-time job. The growth is particularly significant during exam periods; if it were test week all year round, I could probably live without working. Also, as mentioned earlier, maintenance costs are kept low, and since I can maintain the service just by handling minimal inquiries and bug fixes, it is excellent as a (nearly) passive income source.

Advertising Revenue or Subscription?

As for the main revenue sources for the app, there are "advertising revenue" and "subscription." There are many ways to think about which one to use, but for my app, I adopted "advertising revenue" for the following reasons:

  • The average time spent per session is long.
    • Basically, since users edit content (problem sets) within the app, the average time spent per user is relatively long, around 30 minutes to 1 hour, which is compatible with banner ads.
  • The app is not intended for long-term continuous use.
    • Since the usage period for the majority of users is "1 week to 1 month before test weeks or certification exams," it is incompatible with subscriptions, which assume years or months of continuous use.
  • Ads are easier to implement.

Development on Both Native Platforms

For "Anki Maker," I am developing on each native platform, such as Kotlin for Android and Swift for iOS. When I started development (porting) for the iOS version, I wondered whether to use cross-platform frameworks like Flutter or React Native. However, I thought that even with cross-platform development, you would get stuck somewhere if you didn't have native knowledge, and it would be difficult to discern whether a problem was an iOS issue or a cross-platform one. So, I decided to develop natively, partly as a learning experience.

However, as development becomes long-term, it is quite tough for a solo developer to double the effort for fixes. Also, given the functionality of "Anki Maker," there are not many situations where it fully utilizes OS performance, so looking back, I sometimes regret it, thinking "maybe I should have developed it cross-platform." That said, I now feel that being able to create UI designs independently for each is one of the strengths. (discussed later)

Localization

"Anki Maker" is a tool-type app where users create their own problem sets, so there is no need for the developer to prepare content. Therefore, it is highly compatible with localization (all you need to do is change text like buttons). So, I recommend creating an English version at least when you make tool-type apps. Especially, since Android's market share is often higher in countries outside of Japan, the priority for localization becomes high when developing Android apps.

(English localization has been completed for both OSs) As can be seen from the graph above, while the majority of the iOS version is used by Japanese users, the Android version is used in various countries, mainly in Asian nations.

Additionally, I once got carried away with localization and tried to make it multilingual by translating everything in the app using Google Translate. However, it was noticed by local people in a half-baked state, and I received a series of 1-star reviews saying things like "I don't understand the meaning of the in-app text" (for Russian), so currently, I do not perform localization other than for English.

Listening to User Voices

Reviews and Inquiries

Listening to user feedback is extremely important for maintaining motivation for development and making functional improvements. In fact, I try my best to reply to inquiries and reviews I receive at the current moment. However, answering all user requests is not only difficult in terms of man-hours but would also make the direction of the app ambiguous. Therefore, in my mind, I perform feature additions with the mindset of not making "Anki Maker" an app that can do everything. There are several reasons for this:

  • I want to avoid making existing workflows complicated by adding too many features.
  • If the app's purpose becomes blurred, it becomes difficult to gain downloads from search traffic.
  • Maintenance costs increase, making it harder to spend time on major features.

Below are examples of actual reviews and inquiries I received:

  • I want to attach images to questions → Accepted (Judged to be beneficial for many users within the scope of "creating problem sets")
  • I want to be able to answer only the questions I got wrong → Accepted (Judged to be beneficial for many users within the scope of "answering problem sets")
  • I want to keep a daily study record → Rejected (Judged to be achievable by using existing study management tools in combination)
  • I want to check English pronunciation → Rejected (Judged that it is better to use an app specialized for English since the number of users who benefit is limited)

User Testing

Besides reviews and inquiries, I occasionally ask non-engineer friends and family to perform user testing. Especially in solo development, the developer himself understands the behavior inside the application, so there is no "confusion" when using the app. Therefore, seeing and hearing what intent a first-time user uses the app with is a hint for improving the workflows within the app.

Below are examples of actual impressions I received:

  • "I have resistance to pressing a button when I don't know what will happen."
    • Since I am the type of person who tries pressing various things anyway, this was a blind spot.
    • → Instead of overusing icon-only buttons, major features are expressed with "icon + button."
  • "It feels strange that the operation menu doesn't appear on long press on iOS."
    • I was developing in the flow of Android → iOS, so I hadn't noticed this.
      ...

Based on these results, I try to reduce user churn as much as possible by improving workflows within the app and creating help pages.

Example of a help page
https://ankimaker.com/howto/edit_csv

Current Efforts

To make a better application, there is no end to the things I want to do. Under these circumstances, I am currently working on UI design improvements with the goal of "design that doesn't surprise the user." This effort aims to provide an app that is easy to use for users of each OS, leveraging the characteristic of implementing it in both native languages.
Specifically, for Android, I refer to Google's apps (Material Design), and for iOS, Apple's apps (Human Interface Guidelines), aiming for an app that feels as if it were pre-installed on the OS. By conforming to UI components provided as standard by each platform, I hope to reduce implementation costs due to unique customizations and reduce the risk of unintended design breakage due to OS updates. Also, through this policy, I have been able to actively incorporate new technologies around the UI layer such as SwiftUI and Jetpack Compose.

Before Renewal (iOS) After Renewal (iOS)

Conclusion

As I have written up to this point, the fact that you can (and must) do everything yourself is both the hard part and the interesting part of solo development. Creating things while trial-and-erroring how to increase numbers like "number of users" and "revenue" is, in a sense, like aiming for a high score in a game and is a lot of fun. I would be happy if this article inspires even one person to step into the world of solo development.

Discussion

qaynamqaynam

個人開発で頑張っているので、とても参考にできました!✨

4