This article is part 1 of the “The dilemmas you’ll face when creating a web component library” series. If this is the first article in the series you’ve come across, I’d recommend giving the introduction a read first.
You’ve decided that you want to create a web component UI library. Great, that means you’ve thrown away the “which JavaScript framework do I use?” question. With that said, you’re faced your first dilemma, how do you want your end-users to consume your library?
Dilemma 0: Should your users consume your library as a single package or as multiple packages?
Thinking about your end users at this point might seem pre-emptive, but the answer to this question impacts how you structure your repo. The good news is you can always change things down the line if you decide your choice wasn’t quite right.
What are your two options? You can export all of your components via a single package, installing this package will give users access to your entire suite. The alternative is to break your packages into smaller packages, where each component is installable individually.
Single package
Libraries like Ant Design offer a core UI package that provide access to a few dozen components. You’d install via:
npm install antd
and import via:
import { Button, Switch } from "antd"
Multiple packages
Other libraries like Material Web and Lion WC take a monorepo approach, where each component lives in its own sub-directory. This means that each component can be published and installed discretely. Many of these libraries scope their individual components under a single namespace, like so @lion/component-name
. These are known as scoped packages.
If you want to use both Lion’s checkbox and button components, you’ll need to install two separate packages:
npm install @lion/button @lion/switch
and import via:
import { LionButton } from "@lion/button"
import { LionSwitch } from "@lion/switch"
What are monorepos?
If you’re not familiar with the monorepo architecture, it’s a way to structure a single repository to encompass several projects. You can check out Dan Luu’s breakdown of monorepos for more details. Monorepos are a common architecture choice for UI libraries as monorepos afford:
- Simplified dependency management
- Simplified organisation
- Cross-project changes
- Easier refactoring
You can also check out Monorepos: A Multivocal Literature Review which compiles the learnings of dozens of publications on the subject of monorepos.
What about libraries that mix both?
Libraries like Chakra UI and Material UI offer react or core scoped packages, which give end-users access to multiple components via a single package.
You might be concerned about your end-user’s bundles containing unused components. The Open WC offers some best practices for publishing web components, one of which recommends you export your library as ESM. Doing so means your end-user can remove unused code during transpilation.
You can go one step further and allow your end-users to either install individual components or your entire component library. Vaadin is one library that does just this.
Which choice works best for you?
Why would you want to choose one over the other? Consider the following questions:
- Does your library incorporate an opinionated design language
- Does your library encourage the use of several components?
- Do you want to avoid the complexity of creating and maintaining multiple packages?
- Do you expect your end-users to use only a handful of components?
- Do you want the freedom to version components separately? (we’ll get to this more later)
If you answered yes to the first three questions, you’ll want to consider exporting your components via a single package.
If you answered yes to the last two questions, you’ll want to consider separating your components into individual packages.
Does your library incorporate a design language
Both Ant Design and Material UI offer their own ways building UI components. Since Ant Design incorporates their own design language into their component suite, end-users are likely to use multiple components throughout their web apps.
Does your library encourage the use of several components?
As for Material UI, a number of their components can be used together to build complex UI, like the various Dialog* components. This alone makes a case for Material UI to export many components from a single package.
Note: While Material UI uses scoped packages, their material
package exports dozens of components.
For a project like Lion WC, whose components are installable individually, the library offers white-labeled components that an end-user can pick and choose from. This facilitates the workflow where a user may need only a handful of components.
Don’t let the arbitrary segregation deter you from doing something different entirely. Wired Elements is a UI component library that exports all of the components from a single package.
Do you want the freedom to version components separately?
A benefit of managing your components via a monorepo is that you’ll be able to update individual components as they change, and not the entire library at once. We discuss this a little more in my article that tackles versioning.
What did I choose?
For oui-ui, because I envision end-users to only use a handful of components, and to be able to manage component version independently, I chose to make each component its own package.
Next steps
You may, or may not, have chosen to use monorepos for your UI library. If you did, then you’re in luck. In the next article, I’ll help you choose the right tool to help you manage your monorepo. If you didn’t choose to use a monorepo, then no worries! You can jump straight to the article after; how to write your web components.