Across the last two years, Duolingo seamlessly migrated its Java Android app to 100% Kotlin. Among the main benefits this brought, developers improved their productivity and happiness while the Duolingo app became almost null pointer exception (NPE) free. InfoQ has spoken with Duolingo Android and web development leader Art Chaidarun to learn more about their experience.
Since Google made Kotlin its preferred language for Android development, JetBrains' language has been attracting ever more developer interest thanks to its modern feature set. Duolingo, maker of a successful language-learning platform, made the decision to move to Kotlin for Android development in 2018 to improve productivity, stability, and developer happiness.
As Duolingo Android and web development leader Art Chaidarun explains, the transition to Kotlin started with each developer getting some Java code to port to Kotlin and assigning mentorship roles to more experienced Kotlin developers. Particularly noteworthy is the pull request workflow that Duolingo engineers defined to make the conversion to Kotlin as easily manageable as possible. Specifically, for each converted source file, developers were required to generate a pull request containing at least three commits: one containing the results of IntelliJ auto-conversion; a second commit containing the fixes to any compilation errors introduced by auto-conversion; a third commit with changes to make the code more idiomatic.
According to Chaidarun, converting to Kotlin reduced line count by around 30%, with peaks of 90%. Eventually, Duolingo app stability improved greatly and most NullPointerExceptions
and IllegalArgumentExceptions
come from third-party dependencies that do not adopt nullability annotations for the Kotlin compiler. InfoQ has spoken with Chaidarun to learn more about their experience.
InfoQ: Migrating an app to a different language is by all counts a huge effort. Could you pin out the key practices that most contributed to this endeavour success?
Art Chaidarun: The single biggest factor was the choice of language: Kotlin's close similarity to Java meant that it was both easy for developers to learn and easy for the IDE to automatically convert from Java. This holds less true for converting Java to Scala or Objective-C to Swift, for example. It was also important that we had tooling parity (formatters and linters) between Java and Kotlin in place from the start, which enforced consistency and reduced the switching cost.
InfoQ: How good was your experience with the automatic conversion from Java to Kotlin? Which were the most recurrent problems you encountered?
Chaidarun: IntelliJ's autoconverter was crucial to this effort - we may not have even attempted the migration if it didn't exist. It was surprisingly safe, causing runtime issues only in very rare cases related to reflection. The most common problem was that we had to manually add
@JvmField
and@JvmStatic
annotations to converted code for compatibility with Java callers, which was simple to do.
InfoQ: Could you summarize the main factors that improved developer satisfaction?
Chaidarun: Features such as properties, data classes, and standard library extension methods greatly improve Kotlin's signal-to-noise ratio compared to Java's, making code much easier and faster to both write and review.
Do not miss Chaidarun report on Duolingo blog if you are interested in the full details.