Why open source?
The native team at Kickstarter is responsible for building and maintaining features for Android and iOS. We focus on writing well-tested code built with parts that can be easily understood on their own, and to do that we’ve adopted many functional programming techniques. There have been a ton of benefits to this, some of which we couldn’t have predicted at the start. We are excited to share these findings with the developer community.
We started by organizing the Functional Swift Conference. We hosted the first two conferences in 2014 and 2015 at the Kickstarter office, and in 2016 it moved to Budapest. We wanted to give a space for Swift developers, new and old to functional programming, to come together and share ideas.
Building on the conference, we wanted to take our sharing a step further. The idea of open sourcing our apps came up around the time that Kickstarter became a Public Benefit Corporation, putting a commitment to the public good at the core of its company charter. We started thinking about how we could embrace that principle as engineers. We believe that open sourcing will not only give a new level of transparency into our engineering culture, but will also provide useful resources to the global developer community.
It would be impossible for any organization to open source their iOS application without mentioning the monumental contribution Artsy has made in this area. We were very inspired by Artsy’s open sourcing of Eigen and their open-by-default policy in general. They have provided the community with a great service, and we are thankful for the initiatives they have taken.
Some fun things to explore
Here’s a quick glance at a few things we’re particularly proud of:
Screenshotsdirectory holds nearly 500 screenshots of various screens in every language, device and edge-case state. For example, a backer viewing a project in French here , or a creator looking at their dashboard in German and on an iPad here.
- We use view models as a lightweight way to isolate side effects and embrace a functional core. We write these as a pure mapping of input signals to output signals, and test them heavily, including tests for localization, accessibility, and event tracking.
- We use Swift Playgrounds for iterative development and styling. Most major screens in the app get a corresponding playground where we can see a wide variety of devices, languages, and data in real time. Browse our collection of playgrounds here.
- Our first two pull requests on the open source repositories: updating the design of the backer activity feed and updating the design and functionality of the user profile.
The journey to open source
The native engineering team at Kickstarter is coming off a hectic period of development. A year-and-a-half ago, we were only two iOS engineers: Brandon and Gina, who worked on a four-year-old Objective-C codebase, the majority of which was written by Brandon in the early days of Kickstarter. We didn’t even have an Android app.
One winter day, Chris, a backend engineer, expressed interest in building the Android app. He moved over to work on it full-time. Along the way, we hired Lisa, a former summer intern, to help out with Android. Brandon and Gina also jumped in and made great contributions to the project.
In less than eight months, four engineers who had never written production Java code, let alone production Android code, shipped a 1.0. It was a grueling but rewarding experience. The final product was well-received, stable, and a great way for our backers to explore projects.
One of the tools we employed from the start in our Java code was functional programming. Regardless of how difficult it was to write truly functional code in Java, we knew that if we embraced immutable data structures and pure functions to the best of our ability, we would be able to avoid a lot of complexity that creeps into applications. We were naturally led to using RxJava for wrangling UI interactions in a declarative fashion, and we came up with a simplified way of separating the pure logic from the side-effects in our code, very much in the spirit of the Functional Core, Imperative Shell.
The result was a highly testable code base most of which could be fully understood, in isolation, with no concern for how it interacted with the rest of the system. We were quite proud of our code! But once the dust settled from releasing Kickstarter for Android 1.0, we were left with the sinking feeling that we still had this — now four-year-old — Objective-C codebase to poke back alive.
Luckily, our team was quite familiar with Swift and where the community was headed. Brandon had been co-organizing the Functional Swift Conference and Gina co-hosts the Brooklyn Swift Meetup. We not only had extensive knowledge of how we could leverage Swift’s type system to better express the problems we wanted to model, but also, with our Android experience, had the knowledge of how to build an application, from ground up, in a way that allowed us to piece together functional parts with side-effects at the boundaries.
Thus, we embarked on yet another formidable journey: rewriting our iOS app in Swift and creating something that the entire team could share in ownership. We amplified all of the things we learned from our work on Android, many times over. We had an unwavering eye on writing as much pure functional code as possible, writing it in such a way that enhanced testability, and seeing what new things it would unlock for us at every turn. We were so excited by these developments that we gave two separate talks at this year’s Functional Swift Conference about the cool things we were doing (here and here).
As a native engineering team, we often look back at functional programming as the most important tool that empowered us to work the way we do. We were a team of mixed skills, backgrounds and experience levels, and we became a team that could write understandable, well-tested code on both Android and iOS platforms. We found a common philosophical basis of development through functional programming. Most importantly, we tried not to over-identify ourselves as engineers of a specific platform, but rather look at software development as a more holistic discipline.
We’re excited be working in the open and able to share the cool things we come up with more freely, and the challenges we face more honestly. There are quite a few things we look forward to in 2017, including writing our first Kotlin code in Android, exploring new ways of writing declarative views and, of course, the big Swift 3 migration.
If any of this sounds interesting to you, we’re hiring!
The Kickstarter Native Team