In the course of building apps for clients, I often work with some fantastic UX/UI designers. At least one of them, I’ve noticed, does something that seems both familiar and unfamiliar to software developers: she has a series of common screens that many apps use and customizes those to the needs of the client.
Now, creating reusable components is hardly new to software developers; what’s interesting here is the level of the abstraction. Usually, we tend to think of reusing small bits of functionality. Looking at my Podfiles/Gradle files, I see libraries for loading images, dealing with dates, analytics, networking… even some visual effects like Material Design styling. But, with the possible exception of onboarding libraries, I almost never use any libraries that operate on the UX level, or that scaffold out entire screens.
The reasons why not are legion, but what it comes down to is that every app is different. The UI will be different, the model layer will be different, the server will be different, and so on. But in many apps, there are certain sets of functionality that remain more or less the same. Some examples might be the authentication flow (lord help me if I have to write ONE MORE login screen), infinite list to detail, profile to edit profile, and so on. What if there were ways to abstract the differences between those flows in different apps? What would that get us?
Advantages
One advantage seems clear: depending on how much you could abstract, you’d be able to reuse a lot of code. Entire view controllers, even. In this paradigm, you could quickly add whole flows to your application with little effort. The dream here (for me, at least) is to be able to define how the screens interact with the server, and how they look, and have all the rest of the logic Just Work. What really changes between login screens? Logos, colors, and how you interface with the server. If you could abstract out those things, and build the logic that handles errors, validation, making the server call, advancing to the authed screen, etc one time and reuse it in every app you build, you could greatly reduce the amount of time you spend on authentication and instead get to the good stuff.
If you got more ambitious, you could even scaffold whole apps, making white label that much easier. Many apps I make for clients look something like: Splash > Login > Main List > Detail, plus some auxiliary List > Detail flows and a View Profile with optional Edit Profile. Like, that’s pretty much the whole thing. If I could quickly strap together those flows, and just change the model and view layers, I could greatly speed up development and reduce costs for my clients.
Pitfalls
There are some dangers, though. The more code you reuse, the more tightly it tends to get coupled. It would be very easy to make the flows described above only work in specific circumstances, such that they’re nearly useless in most apps.
On the other hand, in an effort to avoid that issue, it could be easy to over abstract things, and make it nearly impossible to use because there are too many knobs and dials to set.
Regardless, it’s always scary to have large amounts of code in your application that you didn’t customize for this specific project. What if you have to tear it out later? What if you can’t make it work for something small down the line, and you end up having to reimplement everything anyway?
Difficulties
And, obviously, there are some difficulties with making this sort of thing in the first place. We’ll need to find good UX flow candidates for this, and make it easy to replace the things that usually change between implementations. What are those things that usually change? How do we abstract them effectively?
Solution
Check out my talk for details on how to do this effectively, then head over to the repo for the technical details:
https://github.com/ThryvInc/thryv-ux-components