How UI Component Architecture can Solve Organizational Problems

Steve Armstrong
Universal Language
Published in
6 min readAug 16, 2017

--

UI components are a deceptively hard problem. It seems just a matter of picking a UI framework, or iterating on some design mocks and everything should be solved. Right?

The problem is that most of our solutions to problems come from studying small projects. On small projects, we could get a way with having one stylesheet, or iterating on top of a UI framework.

In a large organization, with a massive product, this won’t work. Here is a breakdown of what can go wrong:

Lack of Planning and Architecture

  • Designer creates high fidelity mockups for the product
  • The Front End team implements the design into the application
  • The application grows in size
  • As the application grows, the Front End creates a library to “share” the code

Wasted time & Stagnation

  • Product requests a change to one of the components, but that component is now on 20–30 pages
  • The developers hesitate making the change in fear that it will “break” somewhere else
  • Since teams own different parts of the site, developers don’t even know what could break
  • Bottlenecks are created because changes are high risk

Inconsistency

  • Now Product Owner “A” decides that she doesn’t like a select box, so she has the designer mock up a new select box she likes
  • A new one-off component is created that is entered into the code base without the rest of the team knowing
  • Now there are two select boxes
  • That select box change is not propagated across the app
  • Now, not only are there bottlenecks; there are design inconsistencies. There is also a lack of team buy-in to the process

High Risk/Complexity & Spaghetti Code

  • Now someone submits another design request
  • The global stylesheet has grown so much in size it’s impossible to find any styles
  • The component is referencing a base style that would update many things in an undesirable way
  • So style-nesting are created, !important is added and now . . .
  • Another redesign!!!
  • Seriously . . . the developers over it, the designer has already quit, and product is still asking why simple changes are so hard to make.

Luckily, there are very smart people who have worked hard to solve these problems. So how do we solve them? Here is a checklist of how to add some structure:

Step 1: Build a Component Library

Even if your component library is referencing a set of open source components, build your own library and version it. Not only that, create wrappers for all the components in your library. That way, if you need to swap something out, you don’t have to change the external API. You only need to modify the implementation details.

The component library should be the core of your application. All your apps should require from this library. Instead of writing components in you application and “back porting”, work on the components up front. This will produce better code and a more meaningful application.

The other advantage of the component library is that all developers can isolate and observer changes. Especially if you are managing the code in Github and requiring pull requests before merging.

In a monolith application, it’s easy to slip changes into a feature branch that produce inconsistency. With a component library, people are able to push back on cowboy coding.

Step 2: Split Your Monolithic Front End into Smaller Apps

If you have an application with a lot of pages, you should try to move all those pages their own SPA (Single Page Application). The beauty of this system is as follows. When you make a breaking change to your component library, you can make gradual updates to all your applications. It saves you from having to do “one giant update”.

This reduces developer fear of making changes which leads to more productivity. Teams are able to manage updates on their own schedule. There doesn’t have to be one giant organizational push to update a button.

Step 3: Use CSS Modules to Isolate Component Design

CSS Modules allow for two things. One, they get rid of exposure to global classes. That means when you update a class for a component, you know exactly what will be updated, as the scope of the style is relative to the component.

The second major advantage is that developer knows where all the styles live. They don’t have to worry about styles being spread out all over a set of general set of style sheets.

Step 4: Use an Interactive Style Guide as a Contract Between UX, Product and Engineering

Any component library should be able to publish an interactive style guide. This is a middle ground for developers, product and designers to meet. It allows you to isolate your components and work on them independent of the application. You can work faster and see changes quicker. The best part is that once your publish the update, it propagates the changes through the entire application.

One possible approach to an interactive style guide is Storybook. It not only captures the look and feel, but also exposes states of React components. (Support for Vue is in the works!)

Now that you know where all your components live, there is no need to deliver high fidelity mockups every time. Designers can focus more on behavior, information design and researching UX. Developers don’t have to worry about design when starting a new feature. They can focus on business logic and complex behaviors.

A potential flow for this approach would be as follows:

  • A feature request comes through and is broken down into a set of components
  • Front End developers decide if there are new components or changes are needed for the feature
  • If not, then feature development can begin
  • If new features are needed, the developer creates a feature branch in the component library. The changes are reviewed in an interactive style guide by Product, UX and other developers.
  • Once the change or new component has been approved, the branch is moved into master
  • Depending on the change, a new version of the library is created following semver

So remember the story from before? This is a revised version using what we have learned.

  • A design for an application is abstracted into a set of components and developed into a component library. This library should be versioned using NPM. Breaking API or possibly major design changes would warrant a major version change.
  • Parts of the application are broken into SPAs (Single Page Application) with their own package.json. This allows them to upgrade components in a controlled, risk adverse manner.
  • New Components or changes are decided up front before beginning feature development. Product, UX and Engineering can collaborate on component design using an interactive style guide and see a “real” copy of what something will look like on their site. Changes are not feared because if there is risk associated w/ the change, a developer can use versioning to mitigate the impact. Also, component styles are now isolated using CSS Modules, so a change to component “A” won’t impact component “B”
  • UX can now deliver low fidelity mockups that reference components by names. Developers know exactly which components to use and don’t have to “fish” around somewhere in the “shared” code based
  • Another redesign? No problem. We’ll create a branch in our our component library and update all the styles. When we are ready to release, we’ll create a major version update. Problem solved.

Cons?

  1. There will still be believers in the “whole app” update
  2. Breaking up an app into smaller apps may be overkill for the size of some products
  3. Designing components up front requires a lot of discipline in your team. Not everyone is able to abstract requirements and plan accordingly.
  4. Cowboy coding can still happen. Your library and your process need an owner.

This is not an easy jump to make and it takes buy-in from the whole organization. If your goal is to reduce bottlenecks and sloppy updates while increasing the velocity of your team, then this is the approach for you. If you are still a believer in the “push” button update . . . well, good luck! Don’t be surprised when you see velocity decline and costs go up.

--

--