A lot of good things have already been said, but having worked on similar initiatives within larger banks, here are some of my key takeaways:
- 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.
This is all excellent, and I'll add one more sub point to "Avoid becoming a bottleneck at all costs":
- Be backwards compatible. If you need to break backwards compatibility, advertise it widely and put your people towards the migration. Otherwise, only expand the abilities of components, never remove them and only require less, never require more. If you want to remove from what you give or ask for more than you currently require then make a new version of the component (e. g. `components/Button/v2`). Plan for this (e. g. don't ship `components/Button`, ship `components/Button/v1`). Rich Hickey's Spec-ulation talk goes into the principles in some more detail: https://www.youtube.com/watch?v=oyLBGkS5ICk
The reason for this is because your goal is to empower other teams to move faster. The minute that "keeping up to date with the UI library" requires any significant amount of attention you are draining any velocity you added. People will stop (either by not updating or by moving off the library).
> The minute that "keeping up to date with the UI library" requires any significant amount of attention you are draining any velocity you added.
Adding to this: consider that not everyone is reading your release notes weekly or even monthly, and might be coming back to work on something that's been shelved for months.
Having a "breaking changes" page in your docs is incredibly useful when someone is faced with upgrading a project that uses eg v1.1 when your current release is v3.5, as they can quickly find the things that need to change without having to read through 17 pages of release notes.
"Component X was removed in version 3.0, use y or z instead"
"v2.0 changed how configuration works. Instead of always reading the file config.json, there are now several ways to configure, see docs [here]. You can keep using the old file by adding the code: Config.ReadFile('config.json')."
Sorry to pile on to the doom and gloom around this, but I have been at a bunch of companies that tried this and have never seen it work out well.
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 mean starting a component library by building your own from the ground up is an absurd thing to even attempt.
IMO the only really sane approach is to start with a facade around an existing library. This way you get your single interface and your consistent visual style, but you are free to swap out implementations as necessary.
It is really difficult to do, a few thoughts from previous places I've worked at...
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.
I did this! I founded EUI [0] at Elastic and helped teams adopt it. I attribute success to a few factors:
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.
1. Documentation should be more than half of your team's time. If it's well documented, and has copy/paste content, people will use it because they are lazy and you gave them the easiest solution.
2. Don't think of yourself as building the UI library only. Take the time to work downstream in the product and help the product teams convert to the new stuff. If you're seen as friendly and supportive, rather than adding more work on a team, it makes things easier.
3. Constantly show off your work in large gatherings. Most folks aren't aware of cool stuff you're doing or why it might be useful. Show, don't tell.
These things fail when the upstream library team things they are passing things over a wall (npm) to a consumer. Dogfood it by building the product alongside the teams.
Hey Dave! I think your great design was a big factor in incentivizing people to use EUI. When folks can see how much of a boost the library can give a UI, they'll _want_ to use it.
“ 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.”
This is my life right now. Glad to hear someone who has done this managed to survive the ordeal :D
I appreciate your points. Can you share more about how you interacted with other teams? Did you have resources to help implement the components into products? Did you use any tools or meeting formats to gather feedback and listen to needs?
Thank you! As snide mentions a few threads up, we built a documentation website for the library from day 1, which I think helped folks a lot. I'm not a fan of Storybook -- I prefer docs to present components in realistic situations, and to have code snippets live-side-by-side so someone can say "Hey this is exactly what I need" and copy and paste it into their codebase. For example, form docs should have an example of a complete form with validation, accessibility attributes, help text, and so on. This way the docs act as both an advertisement and as a resource.
Regarding tools, I recall a bunch of stuff. YMMV:
* A presentation to the wider team on the goals of the library.
* GitHub issues outlining technical design of the library -- this was useful for getting buy-in from tech leads.
* One of the consuming developers gave a presentation on how she had implemented a UI using EUI.
I think it just comes down to repetition and, as snide alluded, positioning yourself as a servant instead of an authority. Keep beating the drum, share success stories, and demonstrate that you're responsive to the feedback you're heading from the folks downstream. Good luck!
Having both failed and succeeded at this many times in companies from 20 to 1000 people -- here is my advice for you:
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.
I'm an EM at a company doing just this. We built the component library and associated design system, and we're about half way done through the conversion. It's used for all net new work though.
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.
This has been the mission of multiple teams under my management.
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 1: The main folks you should convince to get onboard are actually the designers. The argument I've seen work pretty well is "having a consistent design means your designer don't need to QA quite as often and it raises the baseline quality for everything." Finally "we will have shared components no matter what, we want you to influence them"
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.
> How do you roll out a component library successfully?
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:
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.
Frankly, for any company above a certain size, this feedback is not helpful.
Having consistent, recognizable branding across different products is valuable not only in reducing duplicate engineering time (building X functionality 3 times) but also keeping customers (end users, perhaps paying users) happy, comfortable and familiar with the product.
I'm not advocating building completely from scratch unless you're a Fortune 500 company (and even then the value add is debatable), but rather starting from a known framework and expanding upon it.
If you want people to adopt your system, you should aim for it to be easier to adopt than whatever their alternatives are.
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.
So we had a team with around 40 devs and we switched to a component library successfully. After 1.5 years there is now 10% legacy code still available, but mostly we are good.
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.
Document it well. My company released an internal library, and I wanted to be a good employee and use it, but it was too difficult. There would be a standard component that takes a standard parameter, but it didn’t work. The documentation didn’t say anything. There were 3 different versions of the library, and I couldn’t tell which was the correct one, and none of them were well documented. I was able to hunt down the code to see how the component was defined, and found out they went out of their way to change from the standard, which they probably thought made it easier, but without documentation it sucked.
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.
Why are you doing this? Developer efficiency? Consistency in UI/UX? New behaviors existing libraries don’t support? Some manager thought it would be a good idea?
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?
Work closely with UI designers at the company. Make sure their design process (sticker sheets or whatever) uses the components you're building and vice versa.
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.
Do not reinvent the wheel. Build components on top of an existing component library such as Material UI for example. This way you can utilize an already existing and known approach and ecosystem and just need to extend it to your needs.
Second this. Libraries like Material UI are battle tested and cover the vast majority of components you’re going to need. You can extend or theme them to match your needs and often include a built in design system. The likelihood of building something better from scratch are low.
Whatever the approach the problem is still valid. The existing component library has be extended for on brand customization, and recurring UI/UX patterns used by the designers. You still have to spread knowledge to allow good re-use that ease maintainability, increase consistency and overall quality.
don't do it! I have been at places where it was done and it's awful. sure it looks cool at the beginning but do you really want to maintain a UI library?
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.
- Component libraries must either be co-owned by eng and design, or there should at least be a designer who is willing and enthusiastic about ownership and maintenance. Otherwise the project may decay as soon as it launches.
- 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."
All previous attempts have failed and to me it looks mostly like challenges with communication, processes, priorities, etc.
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.
Our design team has been charged with making a refreshed, design system. That's all in Figma so far. Nothing has touched a real browser or a real device (tablet, phone). I've coached them to _try_ their design system in code sooner than later, to see if it even makes sense in real scenarios. I've coached them that they'll need multiple implementations.
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.
We did this [0] as a 3-devs startup, and it was one of the best things we ever did!
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.
Without knowing anything specific of your situation, it reads like this is meant to replace existing solutions? So start with documentation. Collect what everyone is using, how they are using it, why they are using it, and especially find the special cases. A library has to be a common ground for everyone, but with legacies you always have a million small details which will harm you with a million little cuts. So find them early and plan accordingly.
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.
We started migrating some of our internal tools to https://ui.shadcn.com/ . We did not want to reinvent the wheel because it would take too much effort (and we did try a couple times in the past and we failed). It's easy to customize a shadcn theme for your own brand and you can integrate with Figma to collaborate with designers.
If you are a small startup with less than 20 developers, I would probably use this or another "ready to use" UI components library. Else it may become a distraction from your main objectives.
Note: Our audience is mostly B2B so our users are not too picky on the design/UI part of the product.
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.
IMO this is doomed to fail. Within a project (or at most a team), you can copy approaches like MUI's for making reusable components (https://mui.com/). But at larger scales across the company, there is no way any such system will survive the modern web/app ecosystem turnover. Everything from code to design changes by fashion every 2-3 years and someone will replace you and want to do their own thing and today's grand cohesive design will just be tech debt by next year.
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.
I’ve tried many times, failed sometimes and succeeded others. My only advice is that every failure prior to you is documentation. Treat each prior failure like a codebase, dig in and figure it out. You will find lessons in the past.
you should pick something off the shelf, but if you go through with it, make it open source! then you can share the work, and receive the benefits of community bug reports and contributions. check out HP's Grommet library for a great example.
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.
We need more information about it. Is it a web design system? Should it work on native android and swift? Also Mac, Linux, Windows? Is it React, Angular, Svelte, vue, a mix of them all?
Ideally, don't start from scratch, use as much industry standard software as humanly possible. For example, check the headless UI libraries in React ecosystem.
The biggest success story I know is Bootstrap. Twitter Designers wanted to unify internal "quick and dirty" admin apps to a simple style, and built it as an external facing "product". With strong enough product documentation and a decent baseline of styles that a lot of developers outside of Twitter were using it for even public websites, internal use is just peer pressure and "everyone else uses it".
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.
I’m very much on board with the “thinking it as a product” and I think we’re actually going to be in good position to sell it to other teams since they’re being forced to adhere to common designs - there’s just no help or implementations to get them there. So even if we don’t build something they find as good as their favorite library, we’ll have the upside of being the one that adheres to the design.
I also like your thoughts on “customer support” and I’m considering whether doing hands on help for the teams migrating would also be worth it.
I’m still pondering whether starting with something really hard or doing some of the easy stuff is the right way. Starting with easier stuff would allow us to build a foundation, get to the point where the library is actually installed across products, which could help establish some feedback loops. That said, I really like your point about targeting the most legacy apps. As you say, that might create of following of people that appreciate the work and would spread the word.
Be careful with wording things that way. "There's currently no competition" and "you have to do it anyway" isn't necessarily a product feature, but possibly a reason to be distrustful.
But yes, ease of use should be easier to sell given a status quo with no competition and no existing easy options.
> I’m still pondering whether starting with something really hard or doing some of the easy stuff is the right way.
It's always going to be a hard decision. It can be helpful to bootstrap with the easy projects with simple needs and by volume (raw number of projects) there might be more of them, but when you finally get around to the hard projects you find you didn't prepare enough and need a lot more work, or big rewrites that will upset all your "easy" customers. But, yes, if you start with the hard projects (and those might be by volume the company's largest codebases or user bases) you might see a lot slower progress, a lot slower to get to an "MVP" point, and subsequently a lot slower to establish some of your feedback cycles, but the teams giving you feedback are likely ones that are going to be most appreciative of the hard work, most helpful in helping getting the easy things rock solid while also given you a perspective on the hardest things, and can be indeed be your greatest internal marketers to other teams if they are happy with all of that hard work.
anyone with access to the figma designs can make just about any component library match any design. when i worked at PwC the internal component library was so bad i would build a basic HMTL5 component and use inline styles to match the design.
as a frontend developer i hate using terrible internal library components that are worse than nothing. it becomes a huge bottleneck that destroys velocity.
just think of this: Single Point of Failure for all your applications.
I ran a program like this once for a military unit of 240 organized into 25 teams my second time in Afghanistan. There is only one way this works. Everything else will result in failure. Steps provided in order of priority.
* 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.
We didn’t roll out a component library, but something very similar. Yes, it most likely could have been achieved without deploying to Afghanistan, but the majority of my time on this effort was spent coaching people directly. My team did achieve success in all our business goals though.
A lot of good things have already been said, but having worked on similar initiatives within larger banks, here are some of my key takeaways:
- 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.
This is all excellent, and I'll add one more sub point to "Avoid becoming a bottleneck at all costs":
- Be backwards compatible. If you need to break backwards compatibility, advertise it widely and put your people towards the migration. Otherwise, only expand the abilities of components, never remove them and only require less, never require more. If you want to remove from what you give or ask for more than you currently require then make a new version of the component (e. g. `components/Button/v2`). Plan for this (e. g. don't ship `components/Button`, ship `components/Button/v1`). Rich Hickey's Spec-ulation talk goes into the principles in some more detail: https://www.youtube.com/watch?v=oyLBGkS5ICk
The reason for this is because your goal is to empower other teams to move faster. The minute that "keeping up to date with the UI library" requires any significant amount of attention you are draining any velocity you added. People will stop (either by not updating or by moving off the library).
> The minute that "keeping up to date with the UI library" requires any significant amount of attention you are draining any velocity you added.
Adding to this: consider that not everyone is reading your release notes weekly or even monthly, and might be coming back to work on something that's been shelved for months.
Having a "breaking changes" page in your docs is incredibly useful when someone is faced with upgrading a project that uses eg v1.1 when your current release is v3.5, as they can quickly find the things that need to change without having to read through 17 pages of release notes.
"Component X was removed in version 3.0, use y or z instead"
"v2.0 changed how configuration works. Instead of always reading the file config.json, there are now several ways to configure, see docs [here]. You can keep using the old file by adding the code: Config.ReadFile('config.json')."
Also, encourage and accept PRs from teams that have unmet needs
Sorry to pile on to the doom and gloom around this, but I have been at a bunch of companies that tried this and have never seen it work out well.
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 mean starting a component library by building your own from the ground up is an absurd thing to even attempt.
IMO the only really sane approach is to start with a facade around an existing library. This way you get your single interface and your consistent visual style, but you are free to swap out implementations as necessary.
It is really difficult to do, a few thoughts from previous places I've worked at...
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.
I did this! I founded EUI [0] at Elastic and helped teams adopt it. I attribute success to a few factors:
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.
[0] https://elastic.github.io/eui
Hi CJ ;-)
Hope you're doing well! (I built this with CJ).
I'd add a couple other points.
1. Documentation should be more than half of your team's time. If it's well documented, and has copy/paste content, people will use it because they are lazy and you gave them the easiest solution.
2. Don't think of yourself as building the UI library only. Take the time to work downstream in the product and help the product teams convert to the new stuff. If you're seen as friendly and supportive, rather than adding more work on a team, it makes things easier.
3. Constantly show off your work in large gatherings. Most folks aren't aware of cool stuff you're doing or why it might be useful. Show, don't tell.
These things fail when the upstream library team things they are passing things over a wall (npm) to a consumer. Dogfood it by building the product alongside the teams.
Hey Dave! I think your great design was a big factor in incentivizing people to use EUI. When folks can see how much of a boost the library can give a UI, they'll _want_ to use it.
“ 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.”
This is my life right now. Glad to hear someone who has done this managed to survive the ordeal :D
PS I use ES/Kibana every day, well done
Congrats on this! - and the latter 94 versions ;D
I appreciate your points. Can you share more about how you interacted with other teams? Did you have resources to help implement the components into products? Did you use any tools or meeting formats to gather feedback and listen to needs?
Thank you! As snide mentions a few threads up, we built a documentation website for the library from day 1, which I think helped folks a lot. I'm not a fan of Storybook -- I prefer docs to present components in realistic situations, and to have code snippets live-side-by-side so someone can say "Hey this is exactly what I need" and copy and paste it into their codebase. For example, form docs should have an example of a complete form with validation, accessibility attributes, help text, and so on. This way the docs act as both an advertisement and as a resource.
Regarding tools, I recall a bunch of stuff. YMMV:
* A presentation to the wider team on the goals of the library.
* GitHub issues outlining technical design of the library -- this was useful for getting buy-in from tech leads.
* One of the consuming developers gave a presentation on how she had implemented a UI using EUI.
I think it just comes down to repetition and, as snide alluded, positioning yourself as a servant instead of an authority. Keep beating the drum, share success stories, and demonstrate that you're responsive to the feedback you're heading from the folks downstream. Good luck!
Pro tip:
Start with version 60 to make it look like it's a very mature product ;)
Having both failed and succeeded at this many times in companies from 20 to 1000 people -- here is my advice for you:
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.
I'm an EM at a company doing just this. We built the component library and associated design system, and we're about half way done through the conversion. It's used for all net new work though.
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.
This has been the mission of multiple teams under my management.
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 1: The main folks you should convince to get onboard are actually the designers. The argument I've seen work pretty well is "having a consistent design means your designer don't need to QA quite as often and it raises the baseline quality for everything." Finally "we will have shared components no matter what, we want you to influence them"
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.
> How do you roll out a component library successfully?
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.
Frankly, for any company above a certain size, this feedback is not helpful.
Having consistent, recognizable branding across different products is valuable not only in reducing duplicate engineering time (building X functionality 3 times) but also keeping customers (end users, perhaps paying users) happy, comfortable and familiar with the product.
I'm not advocating building completely from scratch unless you're a Fortune 500 company (and even then the value add is debatable), but rather starting from a known framework and expanding upon it.
If you want people to adopt your system, you should aim for it to be easier to adopt than whatever their alternatives are.
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.
So we had a team with around 40 devs and we switched to a component library successfully. After 1.5 years there is now 10% legacy code still available, but mostly we are good.
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.
Document it well. My company released an internal library, and I wanted to be a good employee and use it, but it was too difficult. There would be a standard component that takes a standard parameter, but it didn’t work. The documentation didn’t say anything. There were 3 different versions of the library, and I couldn’t tell which was the correct one, and none of them were well documented. I was able to hunt down the code to see how the component was defined, and found out they went out of their way to change from the standard, which they probably thought made it easier, but without documentation it sucked.
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.
Why are you doing this? Developer efficiency? Consistency in UI/UX? New behaviors existing libraries don’t support? Some manager thought it would be a good idea?
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?
Make sure you talk to all potential users of the library and work on understanding what their issues are. Take them seriously.
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.
Work closely with UI designers at the company. Make sure their design process (sticker sheets or whatever) uses the components you're building and vice versa.
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.
Don't.
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.
Do not reinvent the wheel. Build components on top of an existing component library such as Material UI for example. This way you can utilize an already existing and known approach and ecosystem and just need to extend it to your needs.
Second this. Libraries like Material UI are battle tested and cover the vast majority of components you’re going to need. You can extend or theme them to match your needs and often include a built in design system. The likelihood of building something better from scratch are low.
Whatever the approach the problem is still valid. The existing component library has be extended for on brand customization, and recurring UI/UX patterns used by the designers. You still have to spread knowledge to allow good re-use that ease maintainability, increase consistency and overall quality.
don't do it! I have been at places where it was done and it's awful. sure it looks cool at the beginning but do you really want to maintain a UI library?
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.
- Component libraries must either be co-owned by eng and design, or there should at least be a designer who is willing and enthusiastic about ownership and maintenance. Otherwise the project may decay as soon as it launches.
- 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."
All previous attempts have failed and to me it looks mostly like challenges with communication, processes, priorities, etc.
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.
[flagged]
Our design team has been charged with making a refreshed, design system. That's all in Figma so far. Nothing has touched a real browser or a real device (tablet, phone). I've coached them to _try_ their design system in code sooner than later, to see if it even makes sense in real scenarios. I've coached them that they'll need multiple implementations.
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.
We did this [0] as a 3-devs startup, and it was one of the best things we ever did!
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
Without knowing anything specific of your situation, it reads like this is meant to replace existing solutions? So start with documentation. Collect what everyone is using, how they are using it, why they are using it, and especially find the special cases. A library has to be a common ground for everyone, but with legacies you always have a million small details which will harm you with a million little cuts. So find them early and plan accordingly.
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.
We started migrating some of our internal tools to https://ui.shadcn.com/ . We did not want to reinvent the wheel because it would take too much effort (and we did try a couple times in the past and we failed). It's easy to customize a shadcn theme for your own brand and you can integrate with Figma to collaborate with designers. If you are a small startup with less than 20 developers, I would probably use this or another "ready to use" UI components library. Else it may become a distraction from your main objectives. Note: Our audience is mostly B2B so our users are not too picky on the design/UI part of the product.
>How do you get teams to use it?
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.
IMO this is doomed to fail. Within a project (or at most a team), you can copy approaches like MUI's for making reusable components (https://mui.com/). But at larger scales across the company, there is no way any such system will survive the modern web/app ecosystem turnover. Everything from code to design changes by fashion every 2-3 years and someone will replace you and want to do their own thing and today's grand cohesive design will just be tech debt by next year.
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.
I’ve tried many times, failed sometimes and succeeded others. My only advice is that every failure prior to you is documentation. Treat each prior failure like a codebase, dig in and figure it out. You will find lessons in the past.
you should pick something off the shelf, but if you go through with it, make it open source! then you can share the work, and receive the benefits of community bug reports and contributions. check out HP's Grommet library for a great example.
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.
We need more information about it. Is it a web design system? Should it work on native android and swift? Also Mac, Linux, Windows? Is it React, Angular, Svelte, vue, a mix of them all?
Seems like a lot of your challenges can be solved with https://storybook.js.org/
Ideally, don't start from scratch, use as much industry standard software as humanly possible. For example, check the headless UI libraries in React ecosystem.
One company I've seen do this fairly well is REI. https://cedar.rei.com/
This is incredibly well-documented. Thanks for sharing.
The biggest success story I know is Bootstrap. Twitter Designers wanted to unify internal "quick and dirty" admin apps to a simple style, and built it as an external facing "product". With strong enough product documentation and a decent baseline of styles that a lot of developers outside of Twitter were using it for even public websites, internal use is just peer pressure and "everyone else uses it".
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.
Thanks for sharing this. It’s really appreciated.
I’m very much on board with the “thinking it as a product” and I think we’re actually going to be in good position to sell it to other teams since they’re being forced to adhere to common designs - there’s just no help or implementations to get them there. So even if we don’t build something they find as good as their favorite library, we’ll have the upside of being the one that adheres to the design.
I also like your thoughts on “customer support” and I’m considering whether doing hands on help for the teams migrating would also be worth it.
I’m still pondering whether starting with something really hard or doing some of the easy stuff is the right way. Starting with easier stuff would allow us to build a foundation, get to the point where the library is actually installed across products, which could help establish some feedback loops. That said, I really like your point about targeting the most legacy apps. As you say, that might create of following of people that appreciate the work and would spread the word.
> since they're being forced to
Be careful with wording things that way. "There's currently no competition" and "you have to do it anyway" isn't necessarily a product feature, but possibly a reason to be distrustful.
But yes, ease of use should be easier to sell given a status quo with no competition and no existing easy options.
> I’m still pondering whether starting with something really hard or doing some of the easy stuff is the right way.
It's always going to be a hard decision. It can be helpful to bootstrap with the easy projects with simple needs and by volume (raw number of projects) there might be more of them, but when you finally get around to the hard projects you find you didn't prepare enough and need a lot more work, or big rewrites that will upset all your "easy" customers. But, yes, if you start with the hard projects (and those might be by volume the company's largest codebases or user bases) you might see a lot slower progress, a lot slower to get to an "MVP" point, and subsequently a lot slower to establish some of your feedback cycles, but the teams giving you feedback are likely ones that are going to be most appreciative of the hard work, most helpful in helping getting the easy things rock solid while also given you a perspective on the hardest things, and can be indeed be your greatest internal marketers to other teams if they are happy with all of that hard work.
anyone with access to the figma designs can make just about any component library match any design. when i worked at PwC the internal component library was so bad i would build a basic HMTL5 component and use inline styles to match the design.
as a frontend developer i hate using terrible internal library components that are worse than nothing. it becomes a huge bottleneck that destroys velocity.
just think of this: Single Point of Failure for all your applications.
I ran a program like this once for a military unit of 240 organized into 25 teams my second time in Afghanistan. There is only one way this works. Everything else will result in failure. Steps provided in order of priority.
* 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.
did you really fly all the way to Afghanistan to build a component library? sheesh
We didn’t roll out a component library, but something very similar. Yes, it most likely could have been achieved without deploying to Afghanistan, but the majority of my time on this effort was spent coaching people directly. My team did achieve success in all our business goals though.
Just create a wrapper around shadcn. Keeps it flexible
or a theme on top of MUI or Tailwind/DaisyUI, etc. This is the only way to not waste months of engineering effort to end up with sub par components.
One big question is whether the devs want/need an internal UI library. If yes, make sure you speak to them a lot to know what they're after.
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.
https://www.primefaces.org/