Philippe Khin
How to build a big feature of an App as a Solo Technical Founder
26 August 2020
Building a feature is not just about writing code 🤔
product
tech
code

As a developer, the process of building a new feature of a product for a company is not the same thing as when you operate as a solo technical founder.

When you work for a corporate, or even for a small startup, the behavior side of the feature generally comes from the business side, where they kind of already curated for you the user's story and what kind of behavior the feature is expected to have. However, those steps have to be done by yourself when you're working alone, that starts from asking yourself the right questions first:

  • is this feature requested by real users of your app?
  • is it better to build this feature now? The timing is really crucial, I'll elaborate on that later.
  • is it worth building it or maybe it might be better to use an existing third-party solution?
  • can I actually code it? Meaning, is it doable given my knowledge and skills in this area at a given time?

To answer these questions, I'm gonna describe my own personal experience by relating to some real features that I've built for my Language Exchange app SewaYou

There are features that are worth and not worth building

I had to learn it the hard way. A few months ago as of this writing, I've built a feature called Matchfinder for my app, which basically allows users with a single click, to find potential language partners whose available time of the day (for a real-life meet up to practice a language exchange session) and the native language matches the one of the user who initiates the Matchfinder search, within the area of the visible Map. To give you the context, here is how the current UI of the app looks like with the Map and Free Time thing:

It wasn't a straightforward feature to build, to begin with, but once it's implemented, I left it for a few weeks, and realize that nobody was using it at all. Part of it was that my app didn't have that many people registered, but also because the feature itself wasn't easy enough to use (though from my point of view, it was just a matter of clicking on a button). This is because the app doesn't have a typical UI/UX of a Language Exchange app where you have a users list, or a Swipe-Match-Talk.

Everything and interaction happens from the map first. Users are displayed directly as pinned on the interactive map. That fact alone wasn't obvious for the average user who doesn't know how to use the app. In addition to that, I added a complicated feature built on top of that UX, which makes things a little difficult to understand. But the most important thing was that given the few number of registered users (that are on the Map), 9 times out of 10, the Matchfinder Search just returns no result because nobody has set up their available time of the day (which is optional) or doesn't drag the map and hit the search button at the spot where a Match could possibly be found.

So I learned something here: the feature wasn't useless by itself, and was pretty convenient, but the app's userbase wasn't ready for that yet, both in terms of the usage and how well the users are educated about the app.

Choosing the timing of implementing a feature is as important as implementing the feature itself

From the above example, I learned that estimating the timing before starting to implement a feature is really crucial. It will help you avoid wasting time to pour your energy that won't be useful or won't be well-received now but would be so later. You have probably seen a lot of famous and big apps out there that lack some obvious and important features and are asking yourself how comes this isn't there yet? For example, the Instagram web version doesn't have the Chat feature that was implemented on the mobile version, for years, because perhaps according to their analytics and mobile/desktop usage metrics, there wasn't a big need and request for such a feature yet, and it was a low priority for them. Better focus on something that might grow the app and dive into the platform that works and pays more dividends.

The timing is not only for how well the users will receive it, but is also directly influenced by your app infrastructure at the time of preparing to implement the said feature. This is an important point! You know, if you're a developer, that most of the time, it's 100 times easier to build a new feature in a blank app than to integrate it to an existing app whose codebase might be spaghetti, no proper and obvious opinionated structure, no modules, no test written etc...

For such cases, it will be better to postpone the feature (if it's not a really critical feature that users can't live without, it can wait for a little while!) until the foundation has been properly laid out. Otherwise, you will just pile up on garbage codes more codes, that will need to be refactored later, and the cost of that will be much higher than if you were to take a step back, and decided to refactor the existing codebase to better welcome new codes of new features. This is also called accumulating technical debt. Of course, as a one-man startup, you have to make a compromise between having to deliver to market fast and maintain your products from a long term point of view.

For example in my case, I'm using JavasScript to build my apps, and I know from day 1 that it'd better to opt for TypeScript which offers type checking at build time, which can save your websites/mobile apps from crashing in production that leads to app reviews/rating (especially mobile apps...). But I was skeptical about using TypeScript since I didn't actually master it and thought it was just overkill for my small app. But over time, the app keeps growing, and it becomes problematic to have data structures spread all across the app without a proper reference or documentation. So I was using inline block comments or a separate knowledge wiki to keep track of the types of my data.

Then after a while, I finally decided to jump into refactoring my whole codebase to TypeScript after seeing the benefits and its ease of use after using it in a different project.

One good thing leads to another, I also decided at the same time to rewrite my app React Class Components into Functional Components in order to be able to use the latest React features including Hooks and Context by deprecating Redux (to be more precise, I used Rematch which is a Redux without the boilerplate and need to add middleware to handle asynchronous actions).

After 10 days straight coding and 70+ commits on GitHub with thousands of lines of code added/deleted and refactored 160+ files, I finished the migration to TypeScript and rewrite my whole app using exclusively React Functional Components. I must say that this is one of the best decision that I've made, since now I'm more confident in my code and the probability that my app crashes in production is much much lower because an object or method is trying to access a field that doesn't exist or something as small and obvious as that.

I also gained more confidence in writing more new codes and features on top of that well-laid-out foundation. Now that everything is documented within the code itself thanks to the power of TypeScript, I'm not afraid of breaking things that easily by adding more features. I can now build pretty big features within hours or days instead of weeks.

I can't stress enough the importance of timing when building new features both on the technical side of the product/app and also the users' side, whether your users are ready to welcome that new feature.

Opting in using a third-party solution is not always the wise thing to do

Do not reinvent the wheel is a motto that we, developers live by, but sometime you'd better off building your own solution rather than using a third-party tool or solution, that includes some open-source as well. A typical example is, for instance, a lot of developers who want to build a Chat feature using React Native tends to use the popular open-source react-native-gifted-chat. Yes it has almost 10k stars on GitHub and is pretty rich in terms of supported feature for a chat.

I also weighed the pros and cons of whether using it or not for my own app. But from experience, integrating a third-party to your app might bring you more headaches in the long run than it helps your app. Yes, you might get the temporary reward by having a chat feature quickly spinning off from day 1, but what if you need to integrate a specific sub-feature to your Chat? You then need to understand thoroughly the API of the provided third-party solution or module, then build on top of that.

Also, the third-party package might bring you more codes and features than you need, which will make your code bloated with a lot of unused codes. For example, if I plan to add some message translation and correction (and later some kind of message rating) sub-features for my chat, then I have to somehow adapt my code to the third-party chat instead of just plugging it seamlessly if I had built the chat by myself.

By building that kind of big features by yourself, it might seem daunting at first, but it will help you maintain more easily your app in the long run, and you'll be able to extend it at will, since you get to know your codebase by heart.

Of course, what I said won't apply for general usage packages like datetime API management (using dayjs or momentjs). But it applies for big modules such as CSS Framework like Material UI. You seem to get the benefit of it at first, but then you'll be bothered so much by the way the API is built/designed at some point (for example you can't write a button text in lowercase in the case of Material UI since it doesn't the Google Material Design guideline). So I just end up writing my own components as well.

What if you can't build the full-blown solution by yourself?

Yep, there are times when you can't build the whole thing by yourself, either because your knowledge is not sufficient enough, or that the feature itself requires more engineering that you can handle by yourself as a solo technical founder.

For example, I wanted to build a video/voice call feature for my app SewaYou and I wanted to implement it by myself by studying and then using WebRTC technology. After some research, it turns out that the implementation wasn't as straightforward as I thought it would be (somehow I expected it though), so I decided to go for the third-party solution but minimizing the vendor locked factor.

Because I can't say clearly how important that feature is to my users. So instead of jumping straight to implementing a complex solution that will take me weeks to build, I'd better start with building some temporary prebuilt package/solution, integrate it to my existing app with the least code dependency as possible and see how the users adopt that feature.

Then after judging that this feature is really used and appreciated by the users, I might code the whole thing by myself by really doing things in an extensible way so that other new sub-features in the future can be built on top of that main feature. You might think: this also applies to the Chat feature! but this will depend on how your app is structured and how deep is the whole chat integration versus the video/call standalone feature.

So after some market/solutions search, I came across an interesting open-source Jitsi, that allows you to have video/voice call in a conference room way (like Zoom), that is, users join a virtual call room, instead of having them call their phone directly like Facebook Messenger

For the moment, the feature is implemented (it took me a week), with some workaround here and there because the package itself does have some known and unknown compatibility issues with some routing/navigation package that I use for my app. The feature does its job, and for now, no further requests from users about extending that main feature, so I can just move on and focus on something else, rather than dwelling myself with that indefinitely.

Your time is limited as a solo founder, focus on what can 10X your business

Over years building my apps, I come to realize that since my time is limited, I can't just sit down and start coding whatever features I feel excited about like the early days. You somehow have to adapt your product to your users' actual needs, and to some extent build features you judge that can bring tremendous values to your business in the long run.

There are times where you have to spend more time talking to your users to reveal needs that they themselves don't even know, and put aside your developer ego to build things that some time might seem boring and not original, but bring values to those who use your products.

Of course, building features then right away tear them down and throw them away is part of the discovery journey to help you understand your product lifecycle as well as how the world perceives it. There are times where your technical standpoint might conflict with your business sense, but those are the times that make you grow as a product maker since experimenting with things is the best way to improve and deliver the best product.

© 2020, Philippe Khin