How to Install a Single Component From any UI Library with NPM + Bit

How to quickly isolate and install single components from any React, Vue or other UI library using Bit and NPM.

Tom Landau
Bits and Pieces

--

There are tons of component libraries out there in the javascript world, and they all follow the same concept: You install the whole library, and then use just one or two components. And that’s far from ideal.

The javascript world is made up of node packages, and those usually contain large pieces of code. This makes sense if you want to use a whole project, but is it a good solution when you need to use only a specific component?

This problem leads to a variety of problems and solutions, ranging from bundling options to project restructuring. In this post, I’ll show how I use Bit to pick a single component from a given library and individually install it via NPM/Yarn without refactoring a single code line.

As an example, I’ll use a real-world React library which is a personal favorite:

A node package for each component?

A couple of years ago I was working as a front-end dev at a big company. As part of a project my team was working on, I was asked to choose a few React components for our application’s UI. I liked Belle, and decided to use it.

However, we didn’t really need the entire library. We needed about 4 or 5 components, to be used in a couple of different apps.

Technically, we could create a package for each function or component, but there’s a reason almost no one does that. The overhead of creating and maintaining a node package is HUGE: You create a repository, set up the environment — configuration, build, test, bundling — and then publish the package. That takes a whole lot of time, and that’s just for one component. What happens if you have dozens of them?

Pick only the components you need

What if we could go over a whole library, choose the component we need just like we pick a tomato at the grocery store, seamlessly isolate the component from the rest of the project, and use it right in our app?

Think about it: we could have access to every part of any given source code project, and install it as an out-of-the-box component for a new app.

Using Bit this workflow not only becomes possible, but also scalable. Instead of installing an entire library, you can isolate and use the components you need, and even develop them right from the new project (that’s another post).

What I’m about to demonstrate can be done by any library’s maintainers to make their components available to the community, or by any community member like me working with open source libraries. Let’s see how it works.

React Belle as a case-study

Let’s say we want to use individual components out of the belle component library. First, we install Bit, and then clone the repository:

$ git clone https://github.com/nikgraf/belle.git

Next, we’ll initialize a Bit workspace in the repo directory:

$ bit init
successfully initialized a bit workspace.

Now we need to isloate the components:

$ bit add src/components/* -t src/__tests__/{FILE_NAME}-test.js
tracking 18 new components
$ bit add src/utils/* -t src/__tests__/{FILE_NAME}-test.js
tracking 7 new components
$ bit add src/config/*
tracking 6 new components
$ bit add src/style/*
tracking 14 new components

Note that we’ve isolated components from four different directories. For the first two, components and utils, we’ve also dynamically added test files.

Dependency resolution — out of the box

Now let’s check the workspace status:

$ bit status
new components
(use "bit tag --all [version]" to lock a version with all your changes)
> components/action-area ... ok
> components/choice ... ok
> components/combo-box-item ... ok
> components/day ... ok
...
...
> components/text-input ... issues found
missing packages dependencies (use your package manager to make sure all package dependencies are installed):
src/__tests__/TextInput-test.js -> react-dom/test-utils
> utils/inject-style ... issues found
missing packages dependencies (use your package manager to make sure all package dependencies are installed):
src/utils/inject-style.js -> react-dom/lib/CSSPropertyOperations

We can see that Bit recognizes missing package dependencies for each component separately. Bit also autmatically recognizes the dependencies between your newly-defined components.

How does it work?
Once you track the components using Bit, each component has an isolated component environment, which ensures its completely decoupled from the rest of the project — the component has other components it depends on, and, of course, node packages it depends on.

This environment enables you to to use and develop components from other projects. For example, components written in typescript can be used and developed in a project written in flow-typed.

Let’s run npm install in order to install the packages, and then check the status again:

$ bit status
new components
(use "bit tag --all [version]" to lock a version with all your changes)
> components/action-area ... ok
> components/button ... ok
> components/card ... ok
> components/choice ... ok
> components/combo-box ... ok
...
...
> utils/inject-style ... ok
> utils/is-component-of-type ... ok
> utils/union-class-names ... ok

Component environments

All is well. Next step is to import a compiler and a tester for the components. Defining a compiler for Bit components allows you to install the component and use its built code directly, and defining a tester will make bit.dev run the component’s tests and display the results, thus helping you make sure the component is functioning properly.

$ bit import bit.envs/bundlers/webpack --compiler
the following component environments were installed
- bit.envs/bundlers/webpack@0.0.13
$ bit import bit.envs/testers/jest --tester
the following component environments were installed
- bit.envs/testers/jest@0.0.32

This is also a major advantage since it saves the overhead of individually configuring these environments for every components/package.

Versioning and exporting the components to bit.dev

Our components are now ready to be versioned and exported to bit.dev, and then used individually.

$ bit tag --all 1.0.045 components tagged | 45 added, 0 changed, 0 auto-tagged

Next, we’ll export the components to a bit.dev scope. bit.dev is the components hub, where you can share and discover components, and it’s free for open source forever.

$ bit export tomlandau.belle
exported 45 components to scope tomlandau.belle

Consuming an individual component — as a package?!

Now that the belle components are on bit.dev, it’s time to go back to out original purpose — using an individual component without the rest of its parent library.

The easiest and most natural way would be to consume it as a node package, right? But then we’re back to the whole overhead of creating and maintaining packages.

Well, every component that is exported to bit.dev is automatically made available to install as a node package from the Bit package registry, using thr NPM client.

First, let’s configure bit.dev as a scoped registry.

$ npm config set @bit:registry https://node.bitsrc.io

Now, let’s see how we can use the Rating component in the user-feedback-sample project.

The first step of consuming a package is installing it.

$ npm i @bit/tomlandau.belle.components.rating

Now we can just import the package in the code and use the component!

Let’s see what it looks like:

What just happened?

We’ve isolated the belle components using Bit, and exported them to bit.dev so they can be shared, discovered, and used individually as packages.

All that was left after that was just installing the package and using the component, without the rest of the library!

The same workflow also works with any other type of Javascript module/component, so you’re not limited to UI components.

But what happens if you want to modify a component? With Bit, you can develop and right from any project using it. Stay tuned for my next post :)

--

--