I'm interested in hearing about experiences (good and bad) with all the above. How do you roll out a component library successfully? How do you get teams to use it? How do you get people excited instead of being a forced rewrite for them? When do you start getting teams on board? How do you set up processes for feedback?
- Treat it as a product. Build something that would be appealing to real world customers. Spent time on writing great documentation, making a website that demos the components and advertise them internally. Even if other teams will be forced to use what you build by company mandate, getting buy-in will make your life much easier.
- Write great documentation. Incorporate usage by other teams as code samples.
- Avoid becoming the bottleneck at all costs. If you ship components to other teams, these components won't do all the things the other teams need. This will create friction for the other team and make you a bottleneck in their development workflow. They won't put up with this for long and quickly start working around your library or ditch it alltogether. To avoid this, make sure you continuously allocate some parts of your team to make fast changes and remain responsive.
- Allow for others to contribute back. Teams won't just use your things - they'll extend it. Make sure you have a clear and structured way to incorporate their changes.
- Stay responsive. Embed your developers and designers within the teams using your library. Don't become "the UI team" that bestows the unworthy with an update at their leisure - get close to your "customers", share their wants and pains.
The problem is that building generalized, actually-in-the-real-world reusable UI components is really, really hard! Generalizing other people's use cases is very tricky without walking in their shoes.
Usually what happens is that a glorious, well-intentioned group within the company puts together a few very short-sighted, yet kind-of-good-looking components for a very specific use case and management sees it and says: "hey, why can't we use this in other projects?" The answer, of course, is that they weren't meant for that! They don't handle about 100 different things that would allow for expanded use in the company. One would need a dedicated team to make it so, which management really doesn't want to pay for.
Trust me, it only gets worse from there...
My advice is to build domain-specific LOB components for your business area and use a real 3rd-party solution for the underlying GUI lib. This actually has a chance of working out. Even doing this is way harder than it sounds lol.
I don't know anything about your technical stack, but I'm going to assume they're all solved for. The easiest is if your codebase is all in a monorepo and all uses the same stack.
It gets a lot harder if you have lots of projects, and you have to build a library that all the other teams have to import.
One way to make this easier, is to make your component library code public, so that a whole class of permissions based issues are avoided.
The rest of the problems, I think are cutural, not technical.
Find an "anchor tenant", that is a fairly big team that own an important product, get that team on board and build something for them. Having a big, high profile team use your library will give smaller teams the confidence to use your library. This is basically using conway's law to your advantage.
Geography plays an interesting role, a place I worked at had 2 major engineering offices in different cities. Each office had developed its own framework, and teams used the framework in the city that they were based in.
Graduates played a valuable role, our grads rotated teams every 6 months for 2 years. They played a huge role in encouraging adoption of libraries, as they'd take learned knowledge from one team to another.
1. Publish components, not styles. This has been rehashed in other HN threads, but the idea is to provide Lego blocks to help engineers build UIs more quickly. This might be out of fashion with Tailwind adherents but we found success by treating the framework's primary interface as React/Vue/JS, not CSS.
2. Be transparent and receptive. Share your goals with consuming teams and ask how you can help them. They might ask for specific components or might ask you to help them convert a UI to use the library. By demonstrating that you and the library are there to serve (as opposed to dictate) you'll earn goodwill and your work will have more impact.
3. Have high-quality components. This applies to the UI design (both how the components look and how they behave) and software design. Are the props intuitive? Do the components compose well? We were fortunate enough to have a strong design and engineering team that did well on this points.
4. Seed the consuming codebase. Patterns in codebases propagate because engineers like to copy/paste. For example, start by migrating all buttons in the consuming codebase over. Then migrate over all forms, modals, and so on. It also helps to take a vertical approach, by migrating a single view entirely over to the library, or building one from scratch. This can get people excited about the library because they can see and experience the end result.
5. Ensure compatibility with the existing codebase. Make sure styles don't collide, make sure the underlying JS libraries are compatible. I chose React for EUI, but the consuming codebase (Kibana) was Angular. We made the decision to convert Kibana to React too, but there was a temporary period where we mounted React components inside of Angular. We needed simple guidelines to support the engineers who were doing that.
Start with the absolute gnarliest, high-traffic, most intricate UIs that are in production now. Design your components to accommodate those most important and valuable use cases, in partnership with the teams responsible for those interactions. If you can handle those, and if you can get those developers to prefer your components because they're easier to work with and they solve the problems the existing tangle is solving, then you will win. Everything else after that will be smooth and easy and it will work.
On the other hand, if you design in isolation, you will likely end up with another beautiful "living style guide and component library" that no one ever uses, because it is not flexible enough to handle real-world interactions, where the designers and product people and engineers all have hard-won legitimate strong feelings about how it all should fit together in the actual product that's making all the actual money.
0. It will be more expensive than you anticipate. Underinvestment will mean failure.
1. Use a headless UI library like radix. It will save your bacon.
2. Dropdowns are hell for us. Spend longer than you expect thinking through all the use cases.
3. Storybook is your friend.
4. This should tie to a design system effort. Zeroheight has a lot of great content about this.
5. Make escape hatches everywhere. Let them make as many changes as they see fit and override anything. Don't expect 100% compliance.
* 5a. You will never have 100% compliance. Don't chase it. It's too expensive.
6. Net new is way easier than retrofit. Connect around an initiative first and consider retrofit a separate effort.
7. Your users will have less front end expertise than you. Design around them, not your experts, but don't make the experts' lives worse.
Are you a designer or an engineer? The perspective below is for engineering:
- Designers are going to be your biggest challenge. There is a wide range of design skill level in leveraging the Figma versions of your design system and you need to have a strong partner in design doing the same thing you are on the dev side.
- Start with primitives. Get everyone using the same colors, fonts, sizes using shared functions. Then introduce theming. This should be universally adopted. Document.
- Rather than roll out a new design system, canonize the most commonly used components into a design system. This way, you get automatic adoption. Speaking of adoption, that's going to be your measure of success.
- Use tools to understand who is using your design system and who is not (there are tools but strong CODEOWNERs files are key here)
- Create documentation and training on the use of the design system. Don't stop teaching others on the use of the design system, especially if they are new to the company.
- Create a contribution model: how and when does a component become part of the design system?
- Take ownership over global components like the nav, headers, and the footer
- I've tried going higher order with form and page builders being part of the design system, but that's a lot harder than it seems
My learning is that a design system is important, but it doesn't get a lot of love in many organizations.
Step 2: Just start building the components. Don't wait for approvals. With enough of a foundation you can show some value and go from there.
Step 3: Show evidence of time savings, how many of those components are used by how many projects.
Step 4: Share a vision and strategy. I really like how others said "don't be the bottleneck" the component library will be left behind if it turns into that. Encourage contributions. Share your roadmap. Encourage incremental and experimental components so that people can share less refined components. Finally clearly indicate what isn't shared and what it will take make something "shared".
I think getting too bogged down in reusability of lots of things is eventually the downfall of component libraries. Additionally, "too much categorization" is also problem. Atomic design for instance is great but I feel like it's a concept to teach designers how to think about componentization and for engineers it actually ends up getting in the way.
If it's going about 70% well at that point, the thing to take it to the next level is to collaborate with design leaders to get them to hold their designers accountable for matching to the design system. They may end up needing to recreate a version of those components in something like figma. If there isn't support for this, the whole system will be a pain till the end of time.
If you can, avoid it. If you must, start with a design system and build on top of that. Let people file issues in your repo and give feedback there. Document your work extensively.
Whenever I'm job searching I ask if a given company has an internal UI component library[0]. If the answer is yes, I take note of that as a red flag.
As for the reason I'll refer to Akin's Laws of Spacecraft Design, specifically point 39:
https://spacecraft.ssl.umd.edu/akins_laws.html
39. Any exploration program which "just happens" to include a new launch vehicle is, de facto, a launch vehicle program.
39. (alternate formulation) The three keys to keeping a new human space program affordable and on schedule:
1) No new launch vehicles.
2) No new launch vehicles.
3) Whatever you do, don't develop any new launch vehicles.
Replace "launch vehicle" with "internal UI component library".
Internal UI component libraries are expensive to produce and maintain - they're much more complex than your average CRUD app and require skilled, disciplined people to actually pull off, as you have to think years into the future and have as little staff rotation as possible.
The organisation I work for, which shall not be named, is on its second attempt at this. Previous was outsourced to another company and that ended predictably badly. The current one is much better and is done internally by a dedicated team, but still documentation is lacking and occasionally there are bugs that would normally compel me to drop a UI library entirely.
All this in a company that employs tens of thousands, of which thousands are developers, so it's not like they can't afford to maintain a project of this scale.
Overall it's hard to do it correctly and it's best to avoid having such a headache on top of your regular development efforts.
[0] Unless of course their business is producing a UI library.
So I would look into where they're losing time because they need to deal with repeated or inconsistent UI stuff, and make those the priority for the library to deal with first.
If you're forcing work on them for no benefit, then you're not going to get any takeup - so I would also budget plenty of time for the kit-owning team to do a lot of the initial rollout until you can get enough of a critical mass.
Some of the steps that we undertook and are not mentioned in other comments.
- We had a migration team set up with 1 developer and the team lead from each team.
- Arranged weekly migration sessions for 2 hours where each team would pick some components and migrate it.
- Made sure that it is the joint responsibility of all the people to maintain the library and not sure a single platform team. This way the teams will at least have more affinity to the components that they have made.
Overall I found the cross team weekly migration sessions to be extremely effective, in such scenarios once people know that it is going to be done on regular basis and it is important, they start giving more weightage mentally.
After spending several days to do what I could do in about 2 minutes with a public library that conforms to some standards and is well documented, I gave up.
Just stay mindful of why you are being tasked with doing this so you can make sure you push it and generate metrics in the right way to demonstrate it is a “success”. There are a couple libraries that generate “demo” websites for React components, those can be flashy and get eyes on your work. You could also generate charts showing adoption rates and other things that make it seem like the library is very useful.
You must have some existing reusable component system as well right? Can you just centralize that and then everyone is already subscribed for once the updates go out?
Don't become a bottleneck. If you don't deliver what's needed, teams often are forced to do their own thing in order to meet deadlines.
Run it like an open source project. Allow others to contribute. Make it easy for them to do so.
Don't lose interest after the first release. Keep up the momentum.
If developers have to twist and contort your components match mocks, then they'll start thinking "you know, this would be a whole lot easier if I just did it myself...". But if the developers get a mock that's obviously just YourDialog containing a YourRadioButtonGroup, YourValidatingInputField, and YourSubmitCancelButtonSet, then they'll just use them.
Think in terms of theming, not reinventing the wheel. Come up with a unified coherent design language, and build out themes for all of the popular existing libraries that anyone wants to use.
Spending a sprint building a select dropdown is not something any engineer should be doing these days.
just like with any other technology: are you writing a blog? don't build a blog-system, use an existing one. are you in the business of letting others build blogs? build a blog-system.
is your company in the business of providing UI component libraries? if not, I would focus my engineering affords on the business, and create a nice skin for whatever UI component library most engineers feel comfortable with.
- Think about versioning early on. Do you want to allow backwards incompatible changes or lock it down? What about dependencies? Will all your components live at the same "level"? Or will some components be used to form bigger components?
- Talk to people. Constantly. You don't want to spend months building something no one will use. Your users are your peers and they're right there. Make sure it solves actual problems, and not just meet the goal of "we now have a component library."
Company standards are a people problem and therefore a money problem. Unless senior management is willing to back the costs of a full transition, it is not going to happen. The costs are lost productivity and involuntary turnover in staff.
Unless you are the chairman of the board, you can't make it happen. If the chairman and the C-suite make it a priority, then it has a reasonable chance of happening. If the initiative comes from any other part of the org-chart, people can resist doing what they are told without much consequence. They will just wait until the initiative runs out of steam just like last time. And the time before that. And the time before that.
Be aware that people are assigned to work on internal standards when things are slow. This doesn't happen when it's all hands, assholes and elbows to the pump. So things are slow at your company. The opportunity you have is to go and get to know the 100 other staff and add them to your professional network. This will help when you look for your next job. Good luck.
At a technical level, there have been previous attempts for these shared design libraries with reusable components. We're mostly using react. The first generation the design system ended up putting all of these complex components like "Product Display" or "Order Builder" and so on, all driven by props. That resulted in prop explosion and increasingly unreasonable maintenance burdens. It also became effectively locked to the versions of React that were available when it was made - teams could not afford to upgrade either their own apps which caused the library to freeze. A second generation of repeated many of those same mistakes, not composable enough, too tied to a definite version of react, too tied to a definite version of mui, and so on. The tech piece, in addition to the people-problems, is just as hard and important too.
Adoption will be driven by funding, value and time.
For us, we found ourselves repeating again and again when we had multiple UI projects. It became boring and we decided to write the design system. It took us about 3-4 months to complete this.
- It takes a LOT of effort to migrate old projects. A LOT! So, make sure you really have the time and effort for a migration like that.
- In my opinion, it only makes sense to have a component library if you have multiple different projects / repos.
- Try not to reinvent the wheel. Design your components library, but follow a pattern of a popular library so you can see "hey if you have used this library, it's the same here. Just the UI is different"
- Write an extensive documentation with examples (here's ours: [1])
- In our case, integrating dark mode, docs, and i18n into the design system (in an opinionated way) saved us a lot of time.
[0] https://github.com/hyvor/design [1] https://hyvor-design.pages.dev
And add as much documentation as possible, but also guides for migration, especially for the special cases. One of the most important parts of such a multi-team-project is communication, so build good connections to everyone, have them involve without annoying them and support them as much as possible for the later migration, if they will be one. And honor that everyone has their own preference, flavors and circumstances, so be open enough in whatever you design to give them some space and flexibility in how they use your components.
Carrot: Thorough documentation with examples, and ease of migration that is as close to 100% automatable as possible, ex. with bash scripts. Migrating should be so easy that your own team could assist with it and not lose cycles.
Stick: Duress and coercion through management alignment, OKR scoring, and deadlines. Bonus if you can involve Legal for regulatory compliance issues resolved by your new components.
At most, you might be able to align your teams along a style guide that dictates how the finished components should look (i.e., trying to standardize their look & feel via Figma files, style tokens, Storybooks, etc.) but NOT how they're implemented in code, especially if you're multi-platform. The difference is of standardizing outputs (what the user sees) vs methods (how the devs code it).
If you force people to standardize code today, all you're really doing is padding your own resume while making their work much more difficult and slowing down the company as a whole. I can guarantee you that some team is going to need to break out of that mold for the next new project, at which point your standards will break down and their innovation will drive new needs and designs and the whole cycle will start all over.
the biggest thing this incentivizes, is to really raise the quality or "production value" of the library. internal-only libraries often suffer from poor documentation, shoddy code, and blockages caused by slow progress and bugs. by releasing the project to the public, your engineers will know that their work will be representing the company.
Unfortunately most of that lesson isn't generalizable. No matter how much Salesforce wanted Lightning to be the next Bootstrap, it was never going to be the next Bootstrap. That's a tiny niche.
That said, as a developer who has gone through several cycles of designers trying to force me to buy into whatever their latest "company wide" component library will be, there are still lessons from Bootstrap to take away starting with the big one: treat it like a product and a service. Treat the rest of the company like your customers and prepare for dealing with complaints, needs, and desires as customer service.
Some related bullet points:
- You are only as good as your documentation says you are. Documentation should be a priority. Documentation should be accurate and up-to-date.
- Have a compatibility plan. Internal branding changes on a whim, don't take that out on your customers. Find ways to support easier transitions from whatever old styles exist. Find ways to make sure that no matter what changes updates are clean and easy with as little rework as possible. Especially that last part, don't hose your early adopters by making them redo everything for "the real production version". Just like with any product launch, your early adopters can be one of your best marketing tools and you can't point to how much they like using your library if you put them through a ringer of rapid changes and constant update struggles.
- Treat as much of the communication as possible as product marketing. Don't tell developers why they "need" or "must" adopt your central styles, sell them on why they should "want" to. Sell an experience of working with it. Sell the features that they can't get from off the shelf tools or the things they might already be using. Mandates from managers and product staff can sometimes get things done faster than marketing and salesmanship can (assuming managers and product staff have the time and money budgets for it and an "all hands do this"), but it doesn't create lasting buy in (especially if it creates resentment) and it doesn't build lasting trust in your project or team (it can generate the feeling that because managers/product did it this time, they'll do it again when the next branding fad or corporate whim comes to mind and they have an excess of budget).
- An internal branding product is only as good as its reach: Can you support the widest variety of technology stacks inside your company? How far back into legacy apps can you reach?
- Can you support the widest variety of technology stacks inside your company? Too many times I've seen these branding products die in the meetings of trying to crown a "best framework" or "chosen tech stack". As a design team, that should never be your role to tell developers what technology to work with, you need to meet them where they are. (In terms of modern technical suggests, CSS is universal and HTML snippet copy and paste can be easily adapted everywhere; if you need to include interactivity in your comments try for as Vanilla JS as possible. Web Components and micro-frameworks for Web Components such as Lit and FAST can be great tools here with wide reach now.)
- How far back into legacy apps can you reach? There's great reason to not want to support IE11, but if your company's internal users are still spending most of their day in IE Mode in Edge to get "real work done" that's what you need to support. Sometimes it is terrible to build for the true lowest common denominator, but the unfortunate corporate reality is that your lowest common denominator will always reflect your overall success in something like component sharing or internal rebranding. On the other side "even 'Legacy App X', that developers hate working on and try to only touch with a ten foot pole, had an easy time adopting some of the new components" can be a great part of a marketing pitch to other teams.
- Maybe try to start with the lowest common denominator and the hard problems: your early adopters should be complex and legacy and excited to spread the message if you did a great job solving their hard problems in their ugly lowest common denominator parts of the company's tech stack. The easy stuff will follow by peer pressure in those cases. (The reverse is far less likely, the hard apps will scoff at the all the easy ones switching to the new stuff as just fad followers and trend sheep. They've seen it before, they'll see it again, their own apps will still be chugging along with same classically bad styles then too.)
- Document everything like a product for external vendors and cheap consultants and pet open source projects. Treat questions/complaints/concerns/desires/needs like product customer service. (Have customer support tools ready on Day 1.) These two I think are important and bear repeating.
* Receive buy in from senior leadership. This has to be more than just some assigned task. Senior leaders must really have your back because the underlings will fight you and resist. Some example might have to be made of some of them. Better one or two of them than you in the position of authority. It really helps when this sentiment is communicated to the team directly by the senior leadership.
* You have to really own it. Accept all failures and successes personally. Be willing to go down with a sinking ship, because that ship is yours. This needs to be visibly obvious to all directly from your communications to impacted personnel without you explicitly stating as much. It should also be absolutely crystal clear that if you are going to drown on this sinking ship there will be a shake up and many of them are going with you. This is one of those rare times when rumors can work in your favor.
* Roll out supporting automation. Write custom ESLint rules and/or TypeScript interfaces to enforce your priorities and integrate them into your build checks on creation of pull requests.
* Your only two technical priorities are the architecture of patterns and the minimum baseline of documentation. It is unlikely you willing be writing this component library on your own so your job is more to provide the definitions. The military would refer to this as a scheme of maneuver and the corresponding documentation would be base orders and fragmentation orders. It is very important to think about this in terms of acceptable baselines, component relationships, and documentation clarity. This is much harder than it sounds.
Good luck.
If it's management thinking that the devs need such a library, or it would cut costs somewhere and the devs have not been consulted - then good luck.