Illustration by Virginia Poltrack

Restitching Plaid

Updating Plaid to modern app standards

Nick Butcher

--

Nick Butcher and Florina Muntenescu

Cutting cloth: Plaid’s origin

Around 4 years ago (2014) I started seeing some of the early design work for what would go on to become Material Design. It got me excited — all of the amazing animated transitions, bold typography and color palettes, animated icons and a tangible elevation model. At the same time Android (Lollipop) introduced a number of new APIs to support building these experiences. I immediately wanted to start prototyping building the kind of designs I was seeing — to figure out how (or if!) you could build this in an Android app. This prototype kept growing as I investigated more interactions and patterns until it was starting to look like a coherent app. I realized that I wanted to open source this to share what I’d learned and put it in the hands of others to showcase what material design could be and how to build it. That’s how Plaid was born and ended up being open sourced in July 2015. It pulls design news and inspiration from APIs offered by Dribbble, Designer News and Product Hunt and displays them in a rich, interactive UI.

Visualizing how elevation reflects and reinforces the most important elements

The major goal of Plaid was to showcase material design and how to build it; providing both education and inspiration. I’m particularly pleased with some of the work on animations and transitions — it was one of the first showcases of shared element transitions and vector icon animation:

Shared element transitions guide users between screens
Icon animations ease state changes and provide character

Fast forward to 2018 and I consider that the app achieved that major goal of being a showcase of material design and how to build it. But all was not good. The two primary data sources it was built upon had changed significantly. Designer News launched v2 of their API which was a major departure from v1 and would require significant rework. Dribbble also launched a new version of their API which removed a lot of the functionality available in v1. With the changes to these data sources, you could no longer access sections of the app e.g. the above text transition into a Designer News details screen no longer worked. It wasn’t meeting its goals any longer.

On top of this the world had moved on. Plaid pre-existed our opinionated guide to architecture & the architecture component libraries and instead used… well no architecture beyond bloated Activities. It also pre-existed the Design support library let alone MDC-Android (which is why it has its own implementations of classes such as FABs or BottomSheets) or Material Theming. While I’d introduced some Kotlin into the project, it was still largely Java based. It had no tests! It had a lot of technical debt.

This technical debt made the prospect of updating the app for the revised APIs or perhaps even adding new data sources pretty daunting. I was contemplating whether I wanted to put in the time and effort investment that it needed… or if I should call it a day and retire the app. That’s when Florina Muntenescu came along with an interesting proposal. Over to Florina…

Plaid 2.0 — still Plaid, different fabric

What do you do when the API your app is getting data from changes or you need to start supporting new features? Do you give up and change jobs or even rewrite the app from scratch? I doubt it. Then why should Plaid, a beautiful, complex app die?

At the same time there are two major shifts happening in Android app development: the introduction of architecture components and Kotlin. While ostensibly separate, the interplay of these two large changes end up influencing each other. But most developers don’t get to start from scratch with these new paradigms, they have an existing code base which they want to migrate.

Could migrating Plaid to Architecture Components and Kotlin help pay down it’s debts and enable it to live on? We think it can!

The vision

Currently Plaid displays content from 3 different sources, and has plans for adding one more. But each of these sources are very different — they have their own APIs, their own capabilities (upvoting, commenting, adding new content etc) and their own details screen. They are only connected through the main feed stream. That means that each source can be encapsulated in its own module, separate from the rest, with interfaces driving the connection between them and with an app module to display the feed.

General vision of Plaid module splits

Having things so modular opens the door to a new realm of possibilities. Every module can be a dynamic feature module, and at run time, we could decide to start loading more data sources. Like this we get to combine 3 important things: code separation, increased build speed, and small APKs.

We knew that inside every module we should take the guide to app architecture as a starting point: having Activities and ViewModels connected via LiveData, a repository encapsulating remote and local data sources. But the business and UI logic that Plaid has is non-trivial, so we need to build on top of the guide to architecture and separate the code even more to ensure we indeed have small classes, each with a single responsibility. Classes that we can easily replace when needed, to provide the extensibility that Plaid needs. To do this, we borrow the concept of use cases from clean architecture and we split every module in 3 layers: data, domain and UI.

  • The data layer contains data sources and repositories.
  • The domain layer holds the business logic, exposed as use cases.
  • The UI layer holds Activities, custom Views and ViewModels but also all of the UI classes that make Plaid the beautiful app that it is now: custom widgets and fancy transitions.

We validate that indeed our architecture is correct, by testing the classes we create.

We knew we wanted to embrace the different programming models Kotlin brings, so we decided to put coroutines at the core of our architecture, helping us easily handle long running work, whilst avoiding callback hell.

Plaid’s main role is to showcase material design, to be an inspiration for designers and developers alike. So this role can’t change! Even more, the way we’re architecting Plaid 2.0 should allow an even easier reusability of UI components in other apps.

The present

We started working on Plaid 2.0 at the beginning of June. We still have a lot to do to achieve the vision described above, but we’ve made a start — the new features have data sources, repositories and use cases, all of these, of course, tested and written in Kotlin.

  • We have a CI, thanks to Tiem
  • The app is split into modules, some even dynamic feature modules, and deployed as an app bundle thanks to Ben
  • Dribbble is no longer using the V1 API and all the broken UI elements are now fixed, thanks to Nick
  • I got Designer News stories and comments, and even login and upvote working

We’re not accepting community contributions just yet while the app is under heavy development, but we promise to do so soon. Until then, feel free to check out our project board that reflects what we’re working on for the current sprint, but also shows a part of our backlog.

Buttoning up

We’re still stitching Plaid back together, facing new problems and finding solutions every day. Most likely similar to problems you’re also facing when architecting your app, moving to Architecture Components and Kotlin. We’re planning on talking (and writing) about them as we go, telling you what decisions we had to make, what we considered, what were the arguments that lead us to a certain path. Follow Plaid on GitHub, and us on our Medium and Twitter accounts for future posts. —The Plaid team (Ben, Nick, Tiem & Florina)

April 2019 update: A new wardrobe

Work on updating Plaid continues but we wanted to update this post with a significant change. Plaid is moving home from github.com/nickbutcher/plaid to github.com/android/plaid to reflect that this has grown beyond a personal app to an official sample that a team of folks are building together. All links to code/issues etc should be migrated and we encourage you to follow along at the new location.

--

--