Kyle Shevlin

Software Engineer
November 06, 2021
0 strokes bestowed

How I Would Use a UI Library

edit

I've recently been working on a project that uses Chakra UI. I've enjoyed using it, for the most part. I've had a few moments that made me go, "Do I want to build my own UI library?" and then immediately snuffed that thought out of existence. Ain't nobody got time for that.

That said, working with Chakra has made me think of an architectural pattern I would be very tempted to employ if I was building the project's design system from the ground up and knew it was going to be a long-living project.

I'll get right to the chase. Here's my idea: for every UI component you're using in the library, create a facade of your own and consume the facade throughout your app. Do not consume the library directly in your features and other component compositions. If I implemented this, I would go so far as to create an ESLint rule that enforced this pattern.

Before I explain all the reasons why, here's a simple facade example. You'll probably think I'm nuts.

import React from 'react'
import { Button as ChakraButton } from '@chakra-ui/react'

export default function Button(props) {
  return <ChakraButton {...props} />
}

I can hear you saying, "Ok, why in the hell would you recommend this, Kyle?" The answer is simple. This creates a lot of flexibility and likely will save me future pain when requirements change at a very low cost now.

"YAGNI! YAGNI! You're Not Gonna Need It!" I hear you scream. Maybe you're right. But I've never worked in a project that lasted a decent amount of time without some upheaval to the UI components.

Here is a short, non-exhaustive list of things you can do easily with this one layer of indirection:

Swap out the library

If you need/want to try a different component library, you can swap out the implementation under the hood without any change to consumers of your UI components (your other developers/teammates). You can make this change component by component. You don't have to do a wholesale, sweeping change.

Add or Restrict props

If you want to add props that aren't on the underlying component, you can do so and map them to some functionality. Or you can create useful aliases to props if they would benefit your team.

Also, you can restrict which props can be used in the underlying UI library. Maybe there's some weird prop you just really want to avoid using. All easily done with a layer of indirection.

Rename/Remap props

If you ever need to rename/remap a prop because of an update to the component library, you can do so without needing to change every instance of that component throughout your app. No codemods. Just one simple change.

How I would implement this

I would start by making two directories: features and ui. I may need to add this to my React project structure post.

Then, every UI component in my app gets a facade in the ui directory. No exceptions.

Finally, I would implement an ESLint rule preventing the import of any third party UI library into the features directory. Features can only import components from other features or the ui directory.

Downsides

I can think of one downside to this approach. Documentation.

Consuming the UI library directly in your app means you rely solely on the documentation of the UI library. If you use the facade pattern, you have to indicate to your consumers where to find the information they need. This means pointing to the documentation of the implementation details, or writing your own docs to cover them. If you end up adding or restricting props, you're going to need to document how the component is used anyways.

Summary

Give yourself some future flexibility by using a facade between the UI library you're using and your features. The extra work could save you a lot of pain down the line.


Finished reading?

Here are a few options for what to do next.

Like
Liked the post? Click the beard up to 50 times to show it
Share
Sharing this post on Twitter & elsewhere is a great way to help me out
Support
Was this post valuable to you? Make a donation to show it
Make a Donation
Kofi logo

Newer Post: My Course Platform
Tags
ReactJavaScript

Kyle Shevlin's face, which is mostly a beard with eyes
Kyle Shevlin is a software engineer who specializes in JavaScript, React and front end web development.

Let's talk some more about JavaScript, React, and software engineering.

I write a newsletter to share my thoughts and the projects I'm working on. I would love for you to join the conversation. You can unsubscribe at any time.

Introduction to State Machines and XState Logo
Introduction to State Machines and XState

Check out my courses!

Liked the post? You might like my courses, too. Click the button to view this course or go to Courses for more information.
I would like give thanks to those who have contributed fixes and updates to this blog. If you see something that needs some love, you can join them. This blog is open sourced at https://github.com/kyleshevlin/blog
alexloudenjacobwsmithbryndymentJacobMGEvanseclectic-codingjhsukgcreativeerikvorhesHaroenvmarktnoonandependabotmarcuslyonsbrentmclarkfederico-fiorinimedayzDoNormal
©2021 Kyle Shevlin. All Rights Reserved.