As of this past December, one of our favorite new features – Duolingo Stories – is available on Android!

Duolingo Stories are quirky, bite-sized tales that learners can read and listen to, all while checking their comprehension with intermittent questions. With Stories, you can improve your reading and listening skills through texts that are longer than the typical Duolingo lessons.

Stories initially launched as a web-only feature in 2017, and bringing them to mobile for both iOS and Android had long been on our roadmap. In this blog post, I will share our process and journey of bringing Stories to Android, including how we did it and the results we’ve seen.

My background

In June 2018, as I completed my third year of college, I began my summer internship at Duolingo, where I got firsthand experience working on the Android app. Since I had never written a single line of Android code before that summer – ever – I knew it would be a challenging experience, but I was ready to dive in head first and start acquainting myself with new, large code bases in languages I had never seen before.

And dive in head first I did: my first project was “Super Duo,” an outfit that users can purchase for our mascot, Duo, to wear in the app. With support from my manager (and possibly a bit of luck), I managed to complete this task on the fourth day of my internship, and then saw the feature in the app by my second week at Duolingo.

Superduo in Shop Superduo in lesson

After graduating in summer of 2019, I returned to Duolingo as a software engineer on Android, and my first project was to work on implementing Stories on Android.

Why we brought Stories to Android

We are constantly thinking about ways to improve the learning experience and offer features that are complementary to our main learning app. Launching Duolingo Stories was our answer to helping learners challenge themselves through longer narratives that don’t exist in the core lessons on Duolingo. Stories are currently available in Spanish, Portuguese, French, and German for English speakers, as well as in English for Spanish, Portuguese, and Chinese speakers. They cover CEFR levels including A1, A2, and B1, which allows learners at different levels to put their language skills to use. See if you can understand what’s happening to María this morning:

Spanish story about María part 1 Spanish story about María part 2

Did you know that more than half of Duolingo users are learning on an Android device? So when we set out to bring Stories from web to mobile, we knew it was important to offer support for Stories on Android. In November 2019, we launched Stories on the iPhone app, and then set our sights on launching on Android as well so that Stories could be accessible to everyone.

How we implemented Stories on Android

This project was a significant undertaking, especially since many of the elements in Stories didn’t previously exist in other parts of the Android app. In tackling this, I knew that prioritizing the key steps would be critical.

One of Duolingo’s operating principles is “Prioritize ruthlessly.” This means that while we value high-quality implementation, we also value our time and make good use of it. Faced with such a big task, I knew I had to limit the scope of the first prototype: the first implementation had nothing more than the elements needed for anyone to go through a story from start to finish. This means that the first Stories lessons done on Android had no challenges, no audio, no illustrations, and were full of placeholders. While it was a very bare-bones version of what the final product would ultimately be, this process allowed me to make necessary changes to the backend support, set up the client architecture, and identify and plan for specific parts of the rest of the project.

Over the course of the project, I was able to develop multiple prototypes regularly for the team to try out. The first users reported critical bugs that I needed to fix and this early feedback was invaluable. For example, a fellow Duolingo engineer uses an Android phone with less-than-average memory size and computing power, and she noticed that on her device, the cover images in the stories list weren’t always appearing as they should have. After some investigation, I discovered that there was a design flaw called “race condition.” This means that when multiple computer programs run at the same time, they can do their jobs in an unexpected order. Bugs like this one were much easier to triage and fix while the code only contained the necessary logic to perform that particular job.

Early testers’ experiences also informed my changes to the software architecture before I added more complexity to the code. During internal testing, we found that the stories list could get out of sync if a user logged out of one account and into a different one. Based on this, I decided to entirely restructure the way I initially set up resource management, so that all of the cache would be correctly indexed by the user. Again, this wouldn’t have been nearly as easy to further into the implementation.

While on the one hand, we want to release new features quickly and care a lot about the results, it also matters how we do it. From the beginning of the implementation, I put great effort into adhering to good coding practices, such as maintaining the model-view-viewmodel architectural pattern, writing readable code, documenting the code, and ensuring that it would be possible to change the behavior at any time. This meant that I couldn’t always take the easy way out. However, if I had only cared about making something that simply works every step of the way, all the vulnerabilities would have quickly added up along this project, and Stories would have become a feature built on top of layers and layers of crutches.

Analyzing the results

Just like everything else at Duolingo, Stories on Android were rolled out as an experiment. As it turns out: learners love them! With Stories on Android, we saw a 3% increase in users actively learning with Duolingo, and those who have Stories are also spending 4.6% more time learning than users who are learning languages that are not yet supported by Stories. At the time of writing this blog post, more than half of Stories users are on Android!


The green line represents time spent learning by users who have Stories, and blue represents control.

Some learners have even taken to social media to talk about their new favorite feature.

Just because we’ve reached the milestone of launching Stories on Android doesn’t mean we’re going to stop iterating on this feature. In fact, it’s quite the opposite: our team works hard to continuously improve every product and feature we offer, and we’ll be doing the same with Stories over the coming months and years – from testing new story formats to offering support for Stories in additional languages. Stay tuned!