Don’t Build Single-Purpose Features

Learn about our journey in building a flexible, cross-platform tool for consistent user experience and communication.

At Babbel, our mission is to create mutual understanding through language. One of the biggest hurdles in language learning is receiving timely and accurate feedback. AI has raised the bar of what’s expected, making personalized feedback not just a nice-to-have but a necessity. This level of personalization helps keep users motivated but also enables them to make tangible progress towards their language learning goals. Yet, delivering the right feedback at the right time is no easy feat.

My team was initially tasked with adding a single-purpose feature to get feedback about a lesson’s difficulty from users, but we quickly realized that we could build a flexible solution that could be reused in many different situations. In just a few months we were able to build a complex and extensible cross-platform backend-driven tool that serves as the main communication channel with our users.  It’s currently used by many teams and helps ensure consistency in the overall user experience and communication. 

At no point did we focus on building a platform and never stopped delivering and testing new features. Nonetheless, we are now in a state where the existing system enables the development and shipping of new features extremely quickly, keeps the user experience consistent, and makes sure our recommendations look and communicate the same everywhere in the app. The following article is about how we balanced feature delivery and platform building and what the role of Engineering is in long-term planning, especially when an exact roadmap is not set.

What We built

Over the past several months, we have been working on a few features to make learning a foreign language more personalized in Babbel. Although we didn’t know what the future held for us, we managed to connect all our work together and build a powerful and flexible system as we went. Later on, I’ll analyze what happened and provide actionable learnings that can be applied whenever new features are about to be built.

Understand the Lesson’s Difficulty

Initially, we wanted to get feedback from our users, to understand how difficult they found a particular lesson. The purpose was to adapt the user’s placement inside all our available content with the main goal of data collection to inform our next steps. At that moment, we saw that showing a screen after a lesson had a lot of potential. In this specific case we want to receive feedback, but this screen could potentially contain any kind of user communication. 

Initial Designs of the lesson's Difficulty Survey
Lesson’s Difficulty Survey

But showing a screen, especially with a simple question, can be done quickly via CRM. We could also just add the code directly in the apps and solve this specific problem. Was this feedback form worth building as a flexible system? It wasn’t a bad idea, but we had more impactful things we could focus on.

After some discussions we saw the potential of having an in-house tool that can show screens after learning activities and use all our internal data instead of passing everything to a 3rd-party tool. Having complete control over the UI was another advantage. We built an API that gets called after lesson completion and returns a JSON with all the required UI data, which is then rendered natively. Our feature was shipped and the Post Activity Feedback system was born.

Supporting More Use Cases

About a month later we needed to start measuring the user’s self efficacy – how users feel about their progress of learning a foreign language. Because we had already built the Post Activity Feedback system, minimal effort was required to add this questionnaire. Adding sliders and adjusting minor things took a sprint and it was ready to go. 

Babbel's Self Efficacy Survey
Self Efficacy Survey

We were able to show the screen after specific lessons at desired periods. Similar use cases included showing a screen on app start welcoming users back after a few days of inactivity. We were able to ship new backwards-compatible features in a very short amount of time. This was when more people saw the potential of the system.

Expand to All Pop-ups

Around this time we noticed inconsistencies about pop-up chains on app start and after completing learning experiences. Trigger logic, pop-up order and tracking had slight differences, which made the overall experience across platforms unpredictable from a product perspective. Without losing too much time, we started to investigate the topic, aligned with necessary stakeholders and started moving all of them to our Post Activity Feedback system. 

But because it had grown and the name was not descriptive we changed it to Dynamic Experience Builder (DXB). The new name was chosen to help with communicating what the system can do. While creating consistent cross-platform queues we also started supporting deep links and the opportunity to open native screens, which live outside of DXB. 

This was the most difficult part because we were touching legacy code and resolving inconsistencies passed down throughout the years. But, because we were consolidating the logic inside the DXB system, we were able to focus on the product and user needs and not be limited technically. The result was clean and predictable pop-ups on all platforms. After this moment all new pop-up screens were required to be part of DXB to keep the user experience predictable. 

Collaboration and Next Steps

After we created basic documentation and invited more teams to use DXB for their features, we saw a big spike in usage. Partly because we required it in certain cases, but also because it enabled extremely fast experimentation. The DXB system is connected to all our internal data and we can run experiments with very precise targeting. 

Now we are at a state where we have a consistent pop-up user experience on all platforms. We are able to measure and adjust it from the backend based on every single user’s needs. The user interface is backend-driven, which unlocks many new potential use-cases without having to be bound to mobile releases. Furthermore, DXB is flexible but opinionated which makes sure anything built with it adheres to our communication and design guidelines.

Let’s Reflect on the Journey

We are just getting started and have big plans for the future of more deeply integrating AI, aligning outside of product user communication, and more. However, we got to a place where it’s good to reflect back on the progress so far and note down what worked and what didn’t. Ideally I want to summarize our learnings and separate out the decisions that made the DXB successful.

Funnily enough, I got some questions about how we were even allowed to build this. After all, our team is in the Engagement cluster and DXB goes way over our goals. I was quite interested in the answer myself and that’s the second reason for this article.

Understand Your Users

Let’s start by highlighting one difference between learning a foreign language with a teacher and by yourself with an app. The former is able to regularly look at your progress and give you personalized suggestions. Maybe you are doing really well and need more challenging material or maybe you have difficulties understanding a topic and need more examples or different explanations. Furthermore, your previous experience and what you do outside of the classroom affects your learning progress. A teacher observes you during class, grades you in tests and adapts your learning plan accordingly.

Now, while we have Babbel Live, where you could literally learn with a teacher one-on-one or with a group, I’m going to focus on the app-learning experience. In the app we have several benefits over teachers with textbooks. Just like with a personal teacher, we can have a unique learning plan based on your specific interests, goals and motivation. Furthermore, we can observe your progress and not only rely on tests to assess how you are doing. On top of that, your learning experience can adapt as you learn by giving feedback through the app and seeing how you are doing. The only thing that was missing was the flexible communication channel between Babbel as an expert and the users. This gap was identified and is where DXB started. Even at the beginning we knew we’re not building a tool to ask about a lesson’s difficulty, but a whole communication system.

Having a long-term vision here is key. It informs you how your feature and underlying system might evolve in the future. There are always time and resource constraints, and compromises will be made, but you need to know which of those are critical to potential future plans. Having a long-term vision also means you can be flexible on the way to getting there. Which features exactly you build along the way or how long it takes are secondary factors as long as you stay focused and the vision is clearly in sight.

How Should Engineering Work

Although we began with a single-purpose feature, in our case the long-term vision included a powerful tool to communicate to the user recommendations and feedback that would completely replace what a teacher does and even provide additional functionality. The way it’s formulated is vague and very high level and that’s by design. There is no need to go deeper and start defining how it will exactly function. What matters most is ensuring effective communication with the user at key moments in their journey.

This future powerful tool would need to have enough information about every user’s learning experience; to know what’s best for them; and to communicate these recommendations to the user. The first two points are separate systems that I won’t go into in this article. The essential part is that here we are defining a platform and not a product or specific solutions.

The last sentence is the most important in this article. Engineering in a product organization, in my opinion, is about making things possible. The product people together with user research, analytics and others will come up with many ideas and experiments and engineering should be able to make it happen. What the future holds and how users respond to specific experiments can’t be foreseen by anyone, but the general direction of the company and what users need should be clear. This is what defines the long-term engineering landscape and not the many individual products built along the way. Therefore, we should build along those lines while delivering products on the way there.

Build Iteratively 

Once you have a good understanding of your users and a long-term engineering plan you are ready to start building the features the product department brought up. From an engineering perspective your goal is to connect the future work with the immediate one. I found that this best works by plotting how likely a future extension is along with how difficult it will be to build it. The goal is to architect your features in a way that the most likely upcoming iterations are easy to build, which would save a lot of time and headaches, and reduce the potential tech debt. To make it easier to understand I’ve prepared the following diagram.

Diagram having the feature's difficulty to build on the x-axis and the feature's likeliness to be needed in the future on the y-axis.
Feature Flexibility Diagram – It all depends on likely and easy is to build features.

Ideally you would want to have most items in the top left quadrant. How likely things are to be built is defined by the product strategy and the known user needs. How easy something is to build is defined by the engineering team based on the current code base and their expertise. The exact placement is also an approximation as you learn more with time, but ideally items shouldn’t move across quadrants. So let’s explore every quadrant separately. 

Maximize – If a feature is likely to be needed in the future you better make sure it can be easily implemented without a ton of refactoring. Additional planning and abstracting some code might be required initially, but there are clear benefits in terms of necessary effort later on. Your goal here is to try and move most, if not all, items from the upper 2 quadrants to this one. The likelier something is to be needed, the easier it should be to build it. 

Minimize – If you know a feature will be needed soon and you don’t plan upfront to accommodate it, then you’re up for headaches. Anything in this quadrant might introduce breaking changes or a lot of refactoring work. Features here are only worth building if the expected return is significant. Otherwise you are better off finding a hacky way or focusing on something else.

Avoid – There are examples where you can easily build a feature, but the real question is – should you? Building everything can increase unnecessary complexity, make maintenance difficult, and user experience inconsistent. Having a clear future vision should help you know when to say no and when to accept suggestions.

Ignore – Similar to the Avoid section, but here we are talking about features that are difficult to build and unlikely to be needed in the future. No point in wasting any time here. If you are wrong and something is in fact needed, it can be accommodated somehow, but most often there are better things to invest your time and effort in other than the ones in the ignore quadrant.

I’ve added some stickies to illustrate the points. For example we knew we would need multiple pages and the ability to open DXB with deep links from emails and push notifications. When the time for implementation came it was like a breeze and everyone was happy – the engineers because we didn’t require hacky solutions, and the PMs because it was done fast. Multiple DXBs is something that we have postponed for a long time until it was actually needed. That’s the moment we introduced a new API version and breaking changes. Again, everything was planned up front and all stakeholders were on board.

Collaborate With Others

Starting alone is best for iterating fast and getting something off the ground. But for any big project, which this one was, you would need to collaborate with others. Let other teams do likely + easy things, while keeping the difficult ones to yourself. This separation ensures enough autonomy and space for collaboration, while still keeping ownership and the system’s architecture to the team with the domain knowledge. 

Later, another Engagement team wanted to communicate the user’s streak. Because we had now made all after-lesson experiences consistent, it was easy for them to make sure the user sees that they started a new streak. However, they had some designs that weren’t really possible with our current implementation. After talking about it we all agreed that they would extend some capabilities and completely drop others to keep our overall plans in line. Now the two components they integrated are used by many other screens. As for the dropped ideas they had – they informed our future plans and will be part of the next iterations of DXB. 

In this specific situation we aligned where their ideas fit in the diagram. For the easy + likely, we aligned, they provided their plans, we gave feedback, and they implemented it. The ones that were difficult + likely were directly dropped as the needed effort didn’t seem reasonable. None of their ideas were ”unlikely to be needed”, as they needed them already. 

Conclusion

As tech advances so does our work, our processes, and most importantly our product. With endless personalization opportunities, partly driven by AI, it’s not acceptable to deliver single-purpose features the exact same experience to all users. I see server-driven natively-built UI as the best way forward. You should fully utilize the vast amount of data you collect on users and give them the best user journey possible. Frontend developers can focus on crafting beautiful UIs, and more of the logic can be handled on the backend. This results in fewer errors, more backwards compatibility, and fancier animations. 

You’ll never know what the future holds. You can learn about your users and market, make detailed plans, and execute on them. While this might work for Product, I believe this doesn’t work for Tech. Our job in engineering isn’t just to  implement features, but to enable building and shipping many solutions. And because we don’t want to put all our eggs in one basket, we need to build a platform that enables many highly-likely solutions. Even if we change direction, having a flexible system, one in which we know how easy and difficult it is to build a whole suite of features, will set us up for the future. 

Want to join our Engineering team?
Apply today!
Share: