Build, distribute and collaborate over components to build multiple projects and applications — a practical guide.
Components drive the development of modern applications. Apart from being UI elements that form the experience for your users, they are also reusable and modular code units which should often be used in more than one project.
When you start diving into the world of building a shared component architecture for your organization, you end up having to figure out some tough questions such as how to develop components independently but avoid the overhead of too many repositories, how to version, publish and manage each component individually, how to help others discover and adopt the components and so on.
These are deep questions, which range from the monorepo experience of component development to cross-repository management of components, and beyond. In this post, we’ll see how you can leverage useful tooling and workflows to develop, distribute and adopt components across projects.
Framework/no framework
You basically have two choices here. The first is to use a framework like React, Angular or Vue. The advantage is that you can enjoy all the scaffolding and advantages of the well-matured framework.
But, you can also choose web-components and their tooling like Stencil etc. The advantage is that these components are frame-work agnostic, which helps reuse and standardize your components across different projects.
Monorepo experience for multiple repositories?
You have to figure out which architecture is right for you. To avoid the overhead of developing each component in a standalone reposiotry, many teams choose to group components into component libraries.
Designated tools like Bit (GitHub) let you develop, build and test individual components in the library in complete isolation. Using Bit, each component in any reposiotry (and library) can be tracked as a standalone unit, and automatically packed it with all its dependencies. Then components can be independently linked to a compiler (zero configs needed(!)), to that they can be built, tested and renders in isolation. Then, components can be versioned and published individually from the repository. When you update a single components, Bit “knows” which other components depend on it, and help you update only the necessary dependency graph of the component.
It also provides additional “monorepo-like” features which are very useful for code-sharing, such as automatic local linking, multi-component configurations control, subsets and incremental builds, cyclic dependencies handling, dynamic workspaces, single NPM install and more.
Another option is to refactor all projects to a monorepo, but that is a massive decision and isn’t required just to share code. You can also other great aid tools (like Lerna) to version and publish components from the repo, but most will require extensive refactoring and configurations and don’t control the dependency graph of components. Either way, try and see what works.
Distribution and consumption across repositories
When you publish your components things are far from over. You have to make sure people can practically find, use and update the components.
Otherwise, you risk puting in all this work for nothing; most people won’t go through much bother to seek your components and won’t adopt components that they can’t modify if they have to. Diving into the whole library and updating it just for one component can be a cumbersome process.
Set up a shared component portal; Make it look good!
Create your component hub in bit.dev
To bring everyone together on your shared components and to consolidate the discovery and consumption of components, you can create your own component portal or just use a cloud-based portal like bit.dev.
The key ingredients provided by such a portal are:
Finding components shared by your team.
Learning about their APIs and playing with live rendered examples.
Consuming individual components to use in different projects.
Ideally, running build and tests for every component.
If you build it on your own, it might take a while but it’s possible. If you choose bit.dev, you get all of the above out-of-the-box alongside features for managing permissions, controlling workflows etc. It will host your components, run their CI, let you save and play with rendered code examples, extract API docs for components and let you install them using npm/yarn.
bit.dev- find, learn, try and install components
Enable a single or bulk components update; not the whole library
You can leverage Bit to version and publish individual components from a reposiotry, and even publish multiple components together as a bulk.
When you make changes to one component, Bit will let you update the version only of the component itself and the components depending on it in the reposiotry, so you don’t have to bump the whole library.
Then, the consumers of these components can get updates only for the components they install (and their dependents), without having to bring in redundant updates for the whole library.
Enable component modifications and updates from any consuming repository; manage and control changes across projects
When you publish components to bit.dev you can do more than just install them as packages; you can bit import the actual source code of the components into any consuming repository. No context switching and you don’t have to dive back to the publishing repo to suggest your changes.
This “cloned” version of the component comes with all the relevant files and dependencies, a linked compiler, and is versioned and managed by Bit. As a result, you can just edit the code and run the build+tests in isolation.
When you are happy with the result just bit tag a new version and export it back to bit.dev. The changes can then be updated into any other project, including the original publiching library. Changes can be merged using Git inside the repo so that you can easily sync component changes everywhere.
Component design system for developers
When you build and share components you are really building a UI component design system. This system has the power to standardize your development and consolidate a consistent and happy visual and functional experience to the users of your applications.
Only instead of just a library, you get a living and breathing component ecosystem within the organization. Instead of a static docs site, you get a component hub with visually rendered components where everyone can easily find, view and even play with the actual components you build.
Visual design system with actual code components
UI components design system: build, distribute, adopt
Through bit.dev the actual code-components (React, Vue, Angular) are rendered and visualized so that both developers and designers can learn exactly how their components look, behave and feel-like to users. They can even play with the components at any moment, in an editable playground.
Developers can easily find and install the components right from the same place where they and the designers can see the visualized components.
When developers make a change and update a version for a specific component, the designers can instantly see the new version and monitor the changes to make sure the actual components fit their design system.
This creates a balance when developers have the flexibility to make changes to a component when they have to, and suggest updates from their own projects, and designers can collaborate to review changes over time.
Component library design system workflow
Using Bit you can build, pack and publish components in isolation in the library. Then, you can export them to bit.dev from where they become a visual design system made of actual source-code components.
From the bit.dev design system components can be installed in other projects, or imported into them to make changes, which in turn can be synced back to the library via bit.dev. This workflow creates a few major advantages:
Modular component development: Automatically encapsulate components in the repository with all their dependencies, link a compiler with 0 build configurations, and you can easily start building, testing and updating components in the repo and only their dependencies. Then, you can bulk-publish your components, each as a standalone package.
Simplified component discovery and consumption: Consodilate your components into one portal from which they are discovered and consumed. Easily update and control changes across projects.
Increased component adoption and collaboration: Let yourself and others on your team suggest changes to components right from their own projects, without context-switching to make a PR in your complex library. Increase the adoption and usage of components, reduce copy-pastes, improve UI standardization and consistency across app and screens.
Conclusion
Reusing components across projects and repositories is all about creating a productive component-economy between your projects and team members. Whether you are working with a library or just sharing components directly between projects, the same 3 keys remain: Develop components as reusable units, distribute them so that people can find and use them, let yourself and others adopt the components and collaborate on changes.
Feel free to check out Bit on GitHub and don’t hesitate to get in touch with any questions, comments or feedback. Happy component development! 🐥
Top comments (6)
This is a great case imho.
Building monorepo component libraries allow people to collaborate on improving current code and reusing an always stable version across projects. Apart from that, it makes it easier to write tests for what you want to achieve and for me personally it allows better knowledge sharing in contrast to "i made a small change to that component in project X".
We use Lerna + Storybook for React/Typescript combo inhouse.
You might want to try NRWL/Nx, comes from the Angular world, but is available for React too (not Vue yet, unfortunately)
I'm a bit confused (pun intended) - is Bit an open-source or a paid platform?
Bit is open-source (and completely free)- you can use it to manage your components by yourself...
bit.dev uses Bit and offers hosting, live playground, search capabilities etc. - you may use it for unlimited component collections for free as long as you keep it public... otherwise, if you need private storage, you can either pay or get a more limited plan...
Do i understand correctly that if i use 10 components in my project that it's 10 extra dependency's in my package.json?
if you have only one project you can have one, single monorepo and import modules directly without referencing any external NPM lib. Only then you would need to have dependencies in package.json, yes. How many, is up to you, you can also provide barrel modules that import other modules, if all your components (or authentication modules or something else) are imported together