Cory House === [00:00:00] Hi, and welcome to PodRocket, a web development podcast. That's brought to you by LogRocket. LogRocket helps software teams to improve user experience with session replay, error tracking, and product analytics. Try it for free at logrocket. com. Hey everybody. I'm Paige Niedringhaus. I am a staff software engineer for Blues, an IoT company. And today we have Corey House with us, who is here to cover his latest conference talk. building reusable components that are actually reusable. Cori, welcome to the podcast. Hi there, Paige. Thanks for having me. Absolutely. So, Cori, you are a React and a JavaScript specialist, and you're the founder and principal consultant at ReactJSConsulting. com. Can you tell us a little bit more about you are to our listeners and your background? Sure thing. So I specialize in React and have been an independent consultant for a number of years here. My history goes back through all sorts [00:01:00] of different technologies. I've been writing software since. Basically the late nineties. So been at it a long while, but once react came along, I really enjoyed it and decided to go all in and build a consultancy around that. So these days I work with about a half dozen different companies every week. And I also author courses for plural sites. So between plural site and consulting, that keeps me busy. I bet it does. I've I've actually watched some of your Pluralsight courses and for anybody who has not, they are excellent. So I would definitely encourage anyone to go out and take a look at them. They're full of great information and knowledge. Wow. Thank you. Absolutely. So today we're actually here to talk about one of your recent conference talks, which is about building reusable components and actually making them reusable. And... Before we get into the meat and potatoes of it, maybe you could talk a little bit about what reusable components are for people who might be less familiar with them. Sure. So [00:02:00] anytime that you're building software, you're going to find yourself repeating different pieces of it. And modern software development offers a lot of options for how to create components and react became popular because of its ability to create components in a very elegant way. At first you created a class. These days you create a function. So it's gotten even leaner over time. But it's certainly not unique in that way. These days, there's probably a dozen or more different competitors that are also very compelling that way. But in the end, when I think about UI components, I think about if I find myself copying and pasting something that looks like HTML, that's a sign that I might want to consider. Creating a component doesn't necessarily mean that I should. And in fact, if I do that too early, then I run into the same sorts of problems that I might have with any other code, where I assume that I know what the abstraction should be. So I go ahead and create that function. And then I realize, okay, that function actually isn't as reusable as I thought, because I didn't know all the use cases [00:03:00] for it. So there are some of those same caveats there, but in the end, reusable components, as far as the UI goes is very similar to any other reusable code. It's just fixated on the user interface. Let's talk a little bit more about some of the biggest trade offs That you touch on in reusable component design. Can you go into some of the specifics for those? Yeah, when you talk about trade offs, I think the real key of avoiding the biggest pain points of the trade offs is designing your components in a way that balances flexibility with opinion. And by that, when we create a reusable component, it's really easy to fall into the mindset of thinking that flexibility is. Obviously a good thing. And as software developers, we love flexibility. We love the idea of thinking, okay, I've written this code and it is so flexible that it can solve not just the problem I need to solve, but a number of other problems that may come up in the future, that's very attractive to most developers. The problem with that [00:04:00] mindset is the term is speculative abstractions where we say. I'm going to try creating an abstraction that's higher level than need be right now, just because I think it might be useful in the future. And that's what I mean by speculative. So the core downside that I see with reusable components and overindexing on them is the blowback that comes from creating components that we find Aren't actually as reusable as we thought. And it's a Sandy Metz has the old saying that the wrong abstraction is more expensive than merely copying and pasting. And I've slightly changed her quote, but it's still, that's the core idea of it is this idea of creating an abstraction isn't necessarily a win. And especially if it's. Speculative and premature. So when I see companies that are struggling with their reusable components, what they tend to have is a situation where they started creating components before they had the requisite foundation. And by [00:05:00] that, they didn't have any clear target painted on the wall. What they had was often. A manager or director vice president that said, we need reasonable components. We know we're going to be working in this technology for a while. So while you're building this app, go ahead and create reusable components. The problem is there's nothing in that recipe that actually is likely to create. Truly reusable components. What tends to happen there is developers fixate heavily on solving the projects problems. And then it's tangential that you happen to get some reusable components out of that. Those components tend to be heavily influenced by the very first project. So you end up in a situation where those components aren't necessarily. Flexible enough for other projects or even necessarily designed in a way that is indicative of the company's opinions. They're indicative of a project's opinions. So you back up slightly, and what you [00:06:00] actually need is a design system. The design system creates a target on the wall that everybody. Is focused on, and a lot of developers may not even be necessarily familiar with what goes into a design system because it's really more a designer needs to come in first and say, we need a design system. And that means we have opinions about a color palette and typography and spacing and voice and tone, and the list goes on here, lots of different things. And by doing that. Then you have very clear guardrails about what your components should look like. And that goes a long way to building components that are actually reusable. Because without that, what tends to happen is the next project comes along and there's a different designer who has a different look and feel and opinion. And so the opportunity for reuse is fostered by having a shared understanding about that foundation, which is the design system itself.[00:07:00] Okay, so in your opinion, you would say that any company that is looking to create a component library, a design system, something that Multiple teams will be able to share and use and hopefully build upon. There should be a team that is dedicated solely to that system, not to a particular end product. Yes, ideally. And I say this partially because I've seen how it works if you don't. And in fact, when I was full time employed years ago, we tried creating a reasonable component library with just people on the side for a while. And what we found was it's very difficult for people to do this sort of thing part time that you need somebody dedicated enough, because it's not merely. The challenge of saying, I'm going to create some reusable components. It's a product. It's something that needs daily feed and caring and support. You need to have fast responses. And in fact, like I [00:08:00] tweeted about this the other day, I was thinking about. All the reasons that I've seen that developers don't use the very components that are available at their company. And it's things like, yeah, it's there, but the team isn't responsive. If I want to change anything, they don't reply. There's a bug that I reported months ago and they didn't fix it. Okay. Mm hmm. If I use this, it has performance problems or it lacks a feature that I need. Like the list is long. And when you're in that situation. As a developer, it's really easy to say, I just won't use that component. I'll just go ahead and go find some other open source component and use that. It's an understandable decision to make, but it also causes a proliferation of inconsistencies if developers continue to do that. So the solution to that is to , think of your component library as a product. Brand it, market it, have a logo for it, have a documentation site that is useful enough [00:09:00] that people can get what they need, that they feel like it's the center of gravity for the whole conversation and iterate on it based on feedback, just like anybody else would a product. And also if it's going to be a product, that means. You need a team around it. In my experience, it's just very difficult to do on the side because of all the things that I mentioned it warrants typically some full time attention that's great advice and everything that you've said up till this point has resonated significantly with me because I, too, have worked at companies where they have tried to build their own design system and It was very painful to use so if you were starting to build a team that was going to be the team that was building your internal design system, what kind of advice would you give to them? Cause it's a pretty daunting task to just be told, here's our color palette. Here is the style of look and feel that we're going for now build all the components that we could possibly need [00:10:00] to be able to build our applications. I agree. That would be a daunting task and I've seen companies try to do it that way. What I actually recommend is that the design team, the UX team, whoever owns the design system. They're also presumably going to be creating all the designs for the application. So if the goal is a common look and feel, and frankly, if you're building reusable components, that needs to be a goal, otherwise your usable components aren't going to be very reusable. So assuming that's there and that's a decision made. I recommend that the design team actually think very carefully about putting these primitives within Figma, assuming they use Figma or whatever similar tool Figma is popular. So what I love to see is. You have these reusable primitives in Figma that represent the components that the developers need to create. And what's useful is in Figma, you're going to name things just like a developer does, and they're going to give this, okay, this is our tab control. This is our tabular grid. This is our heading and [00:11:00] so on. By having those primitives, what it encourages is every application design should be using those primitives. And they're going to be dragging and dropping those things within Figma. They're going to hand those designs over to the component design team, the reusable component team. And they're also going to be referencing those same things in projects. And the place where I've seen this fall down is where this happens. Unfortunately, often where. Designers are naturally creative. They love coming up with new ideas. So when you hire a new designer, they're likely to come in and want to shake things up a little bit. And there's some aspect of that's healthy, but it's also a risk. It's a cost because it means that the components that we have right now aren't going to fit that new idea. So if I've seen reasonable components. Fail on the project side. It's usually because designers are creating [00:12:00] designs that don't really honor the past anymore. They're moving into a new future and they're doing so implicitly. They're not actually telling everybody, Hey, that design system is actually 1. 0. We're creating a new design system, 2. 0. There's going to be a big kickoff. We're going to create. No, it just, a feeling of slowly drifting from what was, and that slow drift can be hard to detect, but it has a very expensive outcome, which is now we're. Out here shopping for another date picker, because the one that we invested all this time and no longer meets the requirements that we're seeing here. That's also something that I have dealt with and you're absolutely right. So one of the things that you mentioned in your talk when you were discussing, how to start treating component libraries as products of their own, or how to get started with one as a company that is just beginning down that path was to actually use an open [00:13:00] source library as a kind of starting point. Could you talk a little bit more about how a company might go about doing that? Silence. part is there are so many out there that it is easy to find something that probably fits most of what you need. The hard part is it can be difficult upfront to realize. The downsides of your decision or how it's maybe painting you into a corner that you don't foresee. You're unlikely to find anything that exactly matches your design system, unless you reverse engineer the whole thing and say, for instance, all right, our design system is just going to look like material UI, at which point. MUI is going to be an easy choice and okay. You're done, but often companies want to have a unique look and feel. And that means you're going to be. Customizing a bit. So on that front there's a number of ways that people get started. Some companies just merely go pick one off the shelf and [00:14:00] say, well, we don't have a design system, but we're going to inherit whatever design opinions are within this component library. There's nothing necessarily wrong with that. Although it does get a little tricky later when they want put in more customizations in that component library might. Offer if they want to make a radical shift, then now, well, your foundation isn't necessarily designed for that sort of thing, so it can be, again, it's helpful to think design system first and to ask, do we have a clear understanding of where we want to be in our branding and our, all these. UI related decisions early. There's also some interesting projects out here that have become very popular recently. Shad CN slash UI, which is a rather strange name. I bring it up because it has a unique way of thinking about things. Most component libraries. You go out there and you run N P M install, and now you have it on your machine [00:15:00] with Shad cn slash ui, it has a generator and it gives you a com command line that generates a component. So you run a command, you get a button. What makes it unique is at that point you have. The button on your side and it's using trusted open source projects behind the scenes, but now you have a nice foundation and it also provides you a number of things that you might forget. Like it thinks it already handles forwarding references. It handles setting the display name . Properly, Now, the And at that point then I could pivot as far as I want to go, because again, I own the code there's also an interesting diff tool as new versions of it come out over time, you can run the diff tool and see how, what they've changed and then figure out how to fix. Your copy effectively. So that addresses some of that concern of divergence over time as well. So I like that model. Although to be clear for [00:16:00] a lot of my clients, I have found. Grabbing a popular component library and just using it more or less as is actually tends to work pretty well because. I think a lot of companies are realizing that their advantage in their industry probably doesn't hinge upon the sorts of things that sit within a design system. That what really matters is, am I solving the right problem? And am I solving it? Well, is it secure? Is it fast? Is it accessible? Is, or do we have good uptime? All the usual things that make good software. So I don't want to make it sound like. Design systems don't matter, but I think that they matter far more because they create consistency and foster reuse and remove decision fatigue. That's what makes them really valuable, but whether it's this font face or this font face or this color palette and this icon set, those sorts of things, I think a lot of companies are [00:17:00] just realizing maybe aren't that important as a differentiation tool. Okay. So, it's minimum viable software at that point. I'm not really worried about the aesthetics. I just want it to be fast and do what I need. So that, and that's a large set of my clients I find is people that are building. Business software for other businesses. B2B software is huge. So a lot of this stuff sits behind a login and the branding is a secondary concern. I think one thing that's interesting about today is, like you said, there are so many different options for design systems that not everybody's website is going to look like a Twitter bootstrap website. There are plenty of different, slightly different styles of buttons, different colors that you can apply that are your own branded colors. There's a lot of ways to make components your own without actually taking on the added burden of building everything from scratch. So it's, It's a lot more customizable than it used to be, I guess. let's Say that you are a [00:18:00] company and you have decided that you're going to build your own component library. One of the things that you mentioned that I think is critical but is often overlooked are The release notes and the change logs and the documentation to actually be able to use these components in the way that they were intended. So I would love if you could talk a little bit more about how you would recommend doing that so that people are actually, they understand what this component should be for and they are, encouraged to keep the documentation up to date and probably in the least painful ways possible as well. Yeah. And this is an area that's, it's easy to overlook too, because there's a good portion of developers that have never actually dealt with running a piece of software that involves true versioning. Like a lot of us are just working on applications and we deploy them all the time and there's no real version number associated with it. So most developers are [00:19:00] familiar with the idea of versioning, , but I'd read recently on Twitter, I loved this take on the way to think about semantic versioning that a major release is actually us saying we made a mistake. And that is such an interesting framing of the major minor fix or a way of thinking about semantic versioning because When we hear major, a lot of people will do what I like to call romantic versioning, where they say, okay, we're going to call this the 5. 0 release. And it, it's just the 5. 0, because we want to make a big splash. We want the excitement around it. There's not actually any breaking changes in here. We just want you to know that we've added new stuff. So in actuality, that should probably be version 4. 5. It's new features. It's not actually. A breaking change as a component library author, that first number, the optics around that are a big deal. And I've, I say this because [00:20:00] people tend to pay attention to it. I've found that. Managers will look at a component library. And for instance, they'll see, Oh, wow, you're on six dot. Oh, they often have negative connotations to that because they recognize that actually represents six breaking versions that occurred. And I've actually had to manage this, the optics of it with some leadership. Because if you're truly honest about semantic versioning and recognizing that it, you have to change the first digit, if you've made a breaking change, that means that even very minor things become a major release because it's a breaking change. So I have had to cringe at times where we put in a major release and it was to fix a typo. In a prop, because that meant that whoever had code that was referencing our misspelled first name. Well, it turns out we, we left a letter out of the prop and we hadn't noticed it. . So [00:21:00] the other thing that tends to happen here is you get Silence. honest, by saying breaking changes or when we have to change the first digit anytime we have a breaking change. And one way that you can limit that somewhat is by saying, let's go ahead and batch breaking releases together. At least that can often be useful. The optics around that are better. It also just avoids that side of churn. But closely related to this is just the idea of having a change log at all. And this is an easy thing to overlook. And it's actually a, I found a surprisingly hard thing to do. Well, there's various tools out there that try to make it easy for you. And those tools generally try to take commit messages and then expose those I don't recommend that the reason I recommend that is commit messages are not intended for my consumers. They're content intended for my fellow [00:22:00] developers, and that's a very different audience. So in my experience, it is best to actually write release notes separately. Now, when I say separately, though, I'm a fan of having those release notes written. And stored in the source control. Like I want to see release notes as part of every pull request. But what I've also found is when you talk about them being part of every pull request, I'm not talking about having a readme file that contains this or a change log dot MD, there's actually two problems with it. One problem is. If, If you and I are working together and we make a change, it's going to create a merge conflict. And if we have a larger team, this problem just spirals. And we end up constantly dealing with merge conflicts. Our CI builds run unnecessarily often because we're always conflicting with each other. Every time somebody approves a request, then one thing gets merged. And now I've got to. Go resolve that I've got to get an approval again, lots of overhead. So what I tend to do is set up a [00:23:00] changelog set up that contains separate files for every changelog entry. And I like to name those changelog entries based on the ticket number. That I associated that change. So this presumes that I have a ticket for every change and most teams have that paradigm anyway. So I've just got a folder. And when I want to open up a pull request, I can even have my CI server check for this and say, Hey, you've opened a pull request, but you didn't actually put in a new file in the change log folder, so. We're not going to have any release notes for this. That's a problem. The other reason I really like this setup is I want to generally work with strong types. So I don't generally work with JavaScript. I try to work with TypeScript. And. I want my release notes to be strongly typed as well. So the reason I want them strongly typed is the same reason I want my code typed. I want basically strongly type slots that say, here's where you put the title. Here's where you put, is it a breaking? Is it a feature? Is it a [00:24:00] fix? Also I want to know what components have changed and I want auto complete support as I go to enter those components. So the whole thing, basically I want to Use a type to enter each one of those. So I actually have a strongly type change log object for that. I call in each one of those files. So it works pretty well. It's actually a I'm wanting to make it an open source project because it's the sort of code right now that I'm just copying between clients. And I have a repo, but it's not really set up yet in a way that's useful for others beyond looking at the pattern, looking at the node. Scripts that I'm calling at the moment. , would you recommend the same kind of thing for doing documentation for , this component library that you're building? Well, I actually recommend starting out as simple as you can, which for most teams tends to be storybook. It's just low friction. Set it up, run it, start putting your components in there. And that tends to work pretty well. There's a point [00:25:00] where some teams outgrow it. And when they do, then I recommend generating your component documentation. By that, your components are written in code. That code can contain comments that. Add metadata around that code. So for instance, if you're building components in react, you're going to have props and props are a fancy word for arguments. Well, I can put a JS doc style comment above every single prop and that comment will flow through. And be read by tools like react doctrine. So imagine that I could take react doctrine. I can point it at a folder and it will read not just the code to know. Okay, here's all the props on this component. Here's the name of the component. But it will also say it will read those comments. It will also read the comment I have above the component itself. So I get all this metadata in Jason format. Well, you can imagine if you give me a bunch of data in Jason format. The sky's the limit. My docs can look like anything. [00:26:00] And so I have built custom doc sites that really slick and work just the way that our designers want to. That's the way to go. Cause what I love is. I know that the docs are right because they're generated from the code. There's really no extra work involved. Once we put in that time upfront and to clarify storybook does a lot of what I just described too, but the downside of storybook is there's, you can only go so far on customizing it because it does have some opinions built in. It also is a little frustrating because it has its own. Dev tooling there. It doesn't actually necessarily leverage the dev tooling that my application uses, so there can be some friction there as well. So there are some benefits to rolling your own, but lots of ways to get it done. . Do you have any advice that you would give for things like visual regression testing? Because I know that is a thing that a lot of teams deal with, they, and it's just been a very difficult thing to automate or test in any real [00:27:00] sense of the word up until this point. Okay. you a blocking. It basically will block pull requests if it finds significant visual changes and you'll need to click a little green button to approve them. As far as tools out there, if you're using storybook, then chromatic is a likely the way to go because chromatic, you can just point it at your storybook stories and it'll generate images of all of those and tell you about regressions if you're outside of storybook, then Percy. Hapo, those are a couple that I've used and had good luck with these. The downside of these is they're not free. . And that's also, in my experience, been the hard sell because companies have to say, well, there's all sorts of things we could be paying for here. Is it worth our money to protect ourselves from this problem? And I will also be [00:28:00] candid that. I've been working in component libraries a lot of years and visual regressions have been an issue. They have happened, but they have happened so infrequently on the teams I've been on that I would have a hard time justifying spending money on the software to protect because it's not merely that I'm spending money on it. I'm also spending time, which is money effectively. And by that, I've got to spend the time to. And maintain these tests. And I, it also means my CI build is now slower. These tend to take a little while, even with good parallelization, you're you've got to run all this, take all these pictures, do the diffs. It's not free that way either. So. I am a believer that a lot of the risk here goes way down in modern development stacks. So for instance, I'm a big fan of tailwind. One thing I really like about tailwind is if I change a style on a given line, I can feel very confident that I didn't go break some other [00:29:00] thing over here because. It's right here. This is the style. So that's very different than CSS, which I often tend to consider basically right once delete never, because it's really scary to delete anything in CSS. I don't have any compiler that can give me certainty. I can try my best to search around and feel fairly confident, but Okay. that's one reason I'm a big fan of tailwind and I've found tailwind can be a. Pretty wonderful fit too, for component libraries as well. If companies decide to go all in on it, because now the other big win is now we're not adding in this other bloated CSS file, we're using the same styles in our reusable components as we are in our application. So you get this nice lean setup there that, that would be very difficult to do by hand. I'm a big fan of how Tailwind solves that problem. Yeah, I have introduced plenty of bugs for myself to figure out why this CSS suddenly stopped working just [00:30:00] by commenting out one class in a completely unrelated file. So yeah, I can. I can agree with you that is the cascade is not always your friend. Okay, so that's a little bit more about, visual regressions, if it's worth it, maybe not at the beginning. What kind of elements do you believe are important to include in the docs beyond things just like the props that a component takes in, or maybe the different things that you're able to tweak or adjust based on Your look and feel or the things that you want to accomplish. What else can you put into docs to help developers be more productive? Yeah. Yeah. Re reactive. Mhm. So one thing that I found useful is unifying the idea of the design system and the developers, or I should say the developer oriented docs. So one of my clients actually on their homepage has two big buttons. And one of them is get started for designers. The other one is get started for developers, because there's a recognition that [00:31:00] if we have. This one site, it operates as a center of gravity for design system and for our reusable components. That's useful because there are times that as a developer, I want to go look at the design system. I need to go reference some of those color palettes or the typography rules or spacing and so on. And I can actually put the developer oriented primitives in there too, and say, if you want to use, say this icon, this iconography, this image, these. Particular colors, here's hex codes and here's import statements and all the like there too. So having a design system and component library on one side, I think is really important. The other things that I've seen is discovery matters. And by discovery, if you've got a bunch of components, it's important to make it as easy as possible for people to find them. So search is an obvious one, but recognize that search. Doing search well is difficult and that's part of why Google became so powerful [00:32:00] because you recognize Google does things like if I make a typo in a name, it's still smart enough to tell me, okay, you probably meant this. And that may seem like overkill for a component library, but here's an example. Sometimes people are going to think that they need a tab control. They might think that they need an accordion and they may or may not be right on that front. They may also be using a term that's different than someone else's. So one example might be an alert, and I'm thinking that I need an alert, but what I actually need is a toast. So I don't actually know what name to type in to search and imagine. I type in. Toast. And it turns out no records come back, but we do have this thing over here called alert that operates exactly like a toast. You should use it as a toast. We just had a different name for it. So when I set up search on my client sites, what I end up doing is having that conversation of, Okay, we need to think about all the other terms that people might use. And it can also even be useful to have [00:33:00] analytics around your search so that, for instance, you want to be able to say people came in and they used our search, here's the terms that they put in, and that may surprise people, you may not realize that certain things are going to happen there. So the the opportunity there is to talk to everyone, to understand what other potential. Terms people use and also to use technology to capture what those are to over time. And Google does this very same thing. When I go to Google and I search, they're paying attention to whether I come back, that's the funny thing is if I come back a moment later, then they want to actually maybe de rank that link. Cause what I gave them was signal. I said, you put this as number one and it wasn't actually what I wanted. So that's how their results get better over time. And we can do that same sort of thing with our own search. Other things in this area is. Related components. So I might find [00:34:00] myself looking at an alert and then realize, okay, there's an alert, but maybe I should actually be using a pop up or maybe I should be using this tool tip over here. So having a related section that actually shows little images of the related components, shows a little snippet and then explains, for instance, You may want to use a tool tip instead. If you have this unique situation, that might be a better choice than this alert that you're using here. So now that's a little funny too, because what I'm describing there sounds like it's giving Advice to developers, but remember, I was saying this site should be useful for designers and developers. And it's this center of gravity. So if people do that, then they're going to find that they actually have people are going to reach for the right tool consistently, because that's another thing that comes up is designers. That [00:35:00] suggest one component that might not actually be the ideal can lead to. Designers asking developers to change a component in a way that isn't ideal. So Right. a tab control is for a particular purpose. And if people are suddenly trying to use that tab control for say, top level navigation and maybe restyle, some things are going, well, that wasn't really how we designed it. Let's talk about maybe using a different tool and that sort of miscommunication can even happen on design teams that have gotten fairly large, where people don't necessarily realize what each component is best used for. And I love the idea of having a component that you're looking at and then Either other names for that component, like you were saying, people search for a toast, but they're looking for an alert in this particular design system as well as having related components. Because there have been so many times where you're looking at the design as a developer and thinking, okay, this is the component that I need to use while a [00:36:00] developer or a designer is thinking of a completely different. Way that component would be used they want it to pop and fade or they want it to just to open up as A side drawer or something else that you know if you are using the same Vocabulary or you have the same set of components that you're looking at It's so much easier to say is this what you were intending or should we be looking at something different like the accordion or the drop? Down or things like that. So I think that's Such a good thing to have and something that is not as common when I think about the design systems that I've used as it should be, it seems yeah. I find it odd for instance, that you can go to material UI always comes to mind for me because they're one of the most popular ones out there and their docs are fantastic, but they don't even quite have what I'm talking about there, they don't have anything in there that helps point out that what I'm looking at might not be. ideal or when I should consider this other thing over here. So that feels like a gap [00:37:00] and credit to the designer that I was working with who showed me this idea. She was fantastic. And she put in a lot of work there because there were other things that she did related to discovery of thinking about a tagging system for components. And that tagging system. Was part of what drove search because the tagging system is effectively saying, we're going to call this a table, but we recognize somebody may consider it a tabular control or a data grid. There are other names for this. So we want to have those tags in there. Those tags can surface in search, but they can also surface even in terms of. Navigation. We could have categorical navigation or different ways to convey the whole list, because if you're talking about a large component library, like the one that we were building ended up with around 75 components, so it's a not long enough lift list that it can feel intimidating. Just see an alphabetized list. You need some ways to discover what you're looking for. Yeah, absolutely. Both of those things are just, they seem like such great ideas that every design system should take into [00:38:00] consideration. Okay. So one of the things that you really briefly talked about was, developer ergonomics and focusing more on that and worrying less about performance. So I'd love if you could talk a little bit more about that because I know performance and react seem to be hand in hand, less re renders and more. Keeping my components from not rendering too often. And why is my component re rendering all those things like that? I'd love if you could talk a little bit more about not worrying so much about the performance and worrying more about the developer. Yeah, I think this has been one of those sort of controversial takes that. React, for instance, is not the fastest library out there. There's a number that have passed it. By a significant margin these days, but it is fast enough. And in my experience, it tends to be plenty fast when used appropriately. And the defaults not doing anything fancy, not reaching for performance [00:39:00] optimizations tend to be sufficient. So I often see teams that are wasting their time trying to optimize for milliseconds when they'd probably be better off spent. Spending their time on other pursuits and reasonable components. It does matter. Performance does matter, but most of the components that we're talking about here that are reusable should be simple enough in the first place that performance is largely a minor concern that the exceptions that I think about are. A date picker can get quite complicated. But yeah, more broadly, I think . There's certainly a risk for making the mistake of writing something that is way too slow because there are some real fundamental design problems with it. But as in reasonable components, generally. I recommend starting out with the simplest API and avoiding any complexities that are merely there for performance reasons, because they often [00:40:00] tend to be unnecessary. And again, this is colored by my experience in react, but those rules may be slightly different in different technologies. But basically, you take the same tact where don't make the reusable component so flexible that it could cover every scenario you can imagine, and many you can't, as, and keep the API simpler to avoid having to then support all those features in the future. exactly. I very much think about how it is easy to add features and it's. It's very hard to remove them and it's hard to remove them because politically it's hard you need. Approval from powerful people up above. And often those powerful people up above are risk averse. They don't want to upset any of their clients. They don't want to lose their jobs. They don't want blow back from their boss. So. Adding features always sounds like a slam dunk, but removing them sounds like oh, it's hard for us to [00:41:00] guess who will be upset. And if the wrong client is upset, even if they're the only user of that feature, you're going to have blowbacks. So I'm. What I generally suggest when you're in a situation where somebody is asking for a feature on a reusable component and it makes you tilt your head and think this probably isn't a good fit. This sounds like a real oddball request. I tend to recommend go ahead and create a new component, create it local. Even go ahead and take the source code from the reusable component and hand it to them and say, go ahead and do what you're doing there. And if it has legs, if it works out and we can see that this is worth doing, we can bring it into the component library, but there's nothing wrong with copying and pasting at first. I really liked Jeff Atwood's rule of three, which says once we've. Copied and pasted a couple of times. Now we've got three examples of this code working in different scenarios. So we've got a good sense that the abstraction has legs. We can see what works and doesn't work. And in fact that's what he recommends. And I've found this really useful as a developer tool to just at times [00:42:00] to say, I got a sense that this is reusable, but I'll go ahead and copy and paste, and then after I've done that, now I can see the commonalities. I can see the opportunities and. It's a separate effort for me to actually go in and design that reusable API. So when you get towards the end of your talk, , you mentioned that there are 10 key decisions for building reusable components, and we've talked a little bit about rigidity versus flexibility. We've talked about using some sort of an open source component components off of. What else would you say are important things to keep in mind or to at least consider as you're going about building a component library or building some sort of a reusable design system for your team or your company? I would say the foundational mindset that I have is tied very much into what I was just talking about, that I want to start opinionated. [00:43:00] I want to start with a component that has a very specific goal and hopefully has very few props on it. And that's because if I do that, everybody will understand what it does. The code will be quite simple. It'll be easy to test. It'll be quite easy to document and yes, there'll be opportunities to make it more flexible, but I would rather those opportunities come up organically rather than speculatively. So this avoids the speculative abstraction thing. It avoids me spending time solving problems that I never needed to solve. It helps me keep my components as lean as I can. So I am, of course, having a conversation with. The design team looking at the given design system, but as much as I can, I want to say, this is how it works and make it easy for people to put in a poll request or a feature request, or to contact you in some way to make these things [00:44:00] better. We know that they're not going to be perfect, but if we can iterate when the time comes in a way that is. Quick and based on considerations around, okay, does this actually honor our design system still? And are we solving a real problem for an actual application? That makes me much more confident that it's worth doing it all. You talked a little bit about React styling, but what would you recommend in addition to Tailwind for approaching React styling? Do you subscribe to CSS and JS? Do you do module CSS styling? What is your, recommendation for that? I recommend tailwind if you can get away with it. I recognize tailwind is one of those things that like, it feels like I'm recommending a religion and a CSS in particular, man, I can't think of any other technology that has. Well, if I want to 80 or 90 tailwind, I can have another volume of people where we[00:45:00] don't really need to just Almost violent with hatred for it, which is weird to me. I actually understand why I largely think that the tailwind hate comes down to, if I'm really good at CSS, tailwind hampers me somewhat. I want full control to do it my way and tailwinds telling me how to do it. And I don't like how it's telling me how to do it. So because of some of those things, I recognize tailwind may not be an option for your team, although frankly, I increasingly feel like the general model of utility CSS and using someone else's utility CSS is a very obvious win. You may not like tailwind in the way they did it, but they are. Very popular for a reason, because effectively they put a huge amount of time into thinking about how to create those utility classes in a way that is broadly reusable. That goes a long way, but if you can't use Tailwind CSS modules is a wonderful way to go. I tend to prefer it [00:46:00] over CSS and JS simply because in CSS modules, I'm writing plain CSS. Very easy to learn, very easy to use. The other thing I like about CSS modules is since it's plain CSS, there is no runtime cost to it, just compiles down. There are some cool, basically modern versions of that. Go check out sprinkles and vanilla extract. Those two go hand in hand. They're basically strongly typed CSS. Modules. But again I feel like, that or CSS and JS, those are great options, but they don't solve the core problem that tailwind does, which is how do I avoid. Bloat in my CSS. How do I avoid the fact that someone else over here is going to write another CSS set of selectors and classes? That's maybe exactly like the one I wrote over here in this other file. And now our CSS file just got that much larger. You can't tree shake that away. Whereas with tailwind, it automatically does [00:47:00] that. That goes a long way. . I do feel like these days, there's a lot of ways to write CSS in a way that largely reduces the pain. I'm happy to say that I don't work with teams that use just plain CSS pretty much ever anymore. Everybody's seems to have decided at least use SAS. And if you're using SAS, probably you want to use BIM along with it so that you have some sort of confidence that you're at least scoping your styles. And then even farther than that. People tend to go a step farther and reach for CSS modules or CSS and JS. Those are two popular options. So yeah, life's gotten much better on that front. And I will also say, ideally you would end up using the same sorts of techniques in your reusable component library that you do in your applications. Just for obvious reasons around being able to hopefully share as much. Technology and code as you can. Well, Cory, it has been an absolute pleasure to talk to you today. Is there anything that we haven't touched on yet that you think is [00:48:00] worth talking about? I'll just say that reasonable components exist because we're making the bet that it's going to be worth it. , it's us saying, we think investing the time in this is going to pay off later. So I'll say nothing wrong with doing this organically. Nothing wrong with just starting out by writing software and then saying, okay. What components make sense. But I do definitely think that a design system is something that most companies can benefit from. Even if you don't create a reusable component library, at least you got a design system that helps Your apps look the same. And with that foundation, you could slowly build those components over time. So if anybody wants to get in contact with you, either to talk about consulting or just to see some of your courses or learn more, where would they find you online? I'm addicted to Twitter, unfortunately. Oh, I'm supposed to say X now. Yeah, I'm on X. Okay. House core, H O U S E, C O R. Uh, You can find me and my [00:49:00] consultancy at reactjsconsulting. com. Fantastic. We will make sure to link all of that up in the show notes and thank you once again for joining us. It's been great to have you here today. Thanks for having me, Paige.