Let's face it React is a way of building component driven applications. So technically we are all doing component driven development. But are we. Are our components really isolated, composed and tested in isolation or are they still coupled together just a little bit!! Let's take a look at how you can really be component driven so you can build, scale and reuse React components across all your React applications.
Taking Component Driven One Step Further
AI Generated Video Summary
React was built for component-driven development. Challenges of component sharing include the inability to easily share components across applications. Monorepos have benefits but can also present challenges such as slow IDE performance and merge conflicts. Onboarding developers and the deployment process can be time-consuming. Bit solves these challenges by allowing isolated and versioned components in a monorepo, providing easy component search, filtering, and versioning, and enabling component-driven development.
1. Introduction to Component-Driven Development
React was built for component-driven development. We're moving towards a component-driven web. This is how we are building nowadays.
♪♪ Taking Component-Driven one step further... Hey everyone, my name is Devi O'Brien, I am Head Developer Advocate at Bit. I'm also a GitHub Star and Microsoft MVP, Google Developer Expert and Media Developer Expert. And you can follow me on Twitter at devs underscore O'Brien. So let's get started.
How it's going, and oops, I completely stole Matt Billman, the CEO of Netlify. I stole his slides from his keynote talk. Sorry, Matt. What he said is how it's going. Number one, he said monoliths are moving to APIs. Number two, Git has transformed the web. Number three, components. Number four, pre-building in JS. And what I want you to focus on is number three, thinking in components. And as he said, the world is moving towards a component-driven world. We're moving towards a component-driven web, and we really need to all be thinking and working in components. Now, you might already be saying, but I'm building in React, and you're totally right. React was built for component-driven development. React was built for components. And basically, what we're doing is we're building in components. So yes, if you're already building in React, you're doing a great job. We are now building component-driven development applications with React.
Cool. So, what's the problem? This is our application. It's amazing. This is my beautiful shoe store, and I have made this application out of components. So that button component is actually only one component that's reused inside that hero component in the theme toggler at the top and also in the product card. So we're building in components, and this is how we are building nowadays. And this is great. This is fantastic.
2. Challenges of Component Sharing
The problem is that the components have no value outside the app. So once I've built that application, all those components, they're kinda stuck inside that application. Now that's a problem. That's not really making component first. You know what happens when we have to build multiple applications? We've got like this amazing application and all these components. What do we do? So really you need another solution. You basically wanna be able to easily share those components across those applications. And there are a couple of options out there, of course.
The problem is that the components have no value outside the app. So once I've built that application, all those components, they're kinda stuck inside that application. Now that's a problem. That's not really making component first. You know what happens when we have to build multiple applications? You know, along comes the product manager, says, we need to build another app. What do we do now? We've got like this amazing application and all these components. What do we do?
So we've got now three applications and a lot of these components are similar. We're building similar e-commerce application. So we've got like, you know, big components like that shopping cart. I wanna rebuild that whole component again and again. I mean, yeah, just a simple button, copy paste it, put it in there, be fine. Or will it? There'll be inconsistency across all your applications eventually. Especially if you scale and grow and grow and grow. So really you need another solution. You basically wanna be able to easily share those components across those applications. And there are a couple of options out there, of course. You know, and you could just basically package them to NPM and hope for the best. I mean, there's a lot of work involved in that. It is possible but it's painful and we don't want pain, right?
3. Challenges of Monorepos
Monorepos allow for scaling applications, improving velocity, and enabling code sharing. However, tooling limitations, slow IDE performance, merge conflicts, and visibility issues can arise. Making API changes in a monorepo can be challenging due to the lack of visibility into component usage.
And one of them is to work in monorepos. Now a lot of people do this. A lot of people are very happy working in monorepos because it allows you to scale those applications, put loads of applications inside the one repo. And when you do that, you can improve velocity. So you can just like build more and more applications really easily because you have access to all the code from each of those applications.
That means you can do code sharing really easily and reuse any of those components in any of the applications. So the dev experience is actually pretty good, right? Because you have access to everything, so it's easy for you to just, you know, build stuff from anything that's in that repo. And if you have to refactor any of those components, well, it's kind of pretty easy too because, like I said, you've got access to them. And cross-team collaboration, you're working with all the team members on this. So, you know, it's pretty good. And you've got some standardization going on because you've just got one repo to maintain. So everything's running on the same standardization. So this is a good point.
Unfortunately, with monorepos, there are a couple of issues. The tooling wasn't built for monorepos. So the tooling really isn't there. Your IDE can get slow because you've got so much code to load. And, you know, you've got, like, get pull, get push again. It's gonna be quite slow because you've got so much to pull down. When your teams are getting bigger and bigger and bigger and more people are making changes to that main branch, you've got all those, like, merge conflicts to deal with. And you're constantly, like, bringing those new changes in.
Visibility and discoverability, this can kinda go both ways, right? Because you could say, oh, in a monorepo, I can actually see all those components that are available to me. And you can, you can see all the code. But you can't really see what the component looks like. You'd have to, like, which app is it being used in? And you'd have to try and find that application to see what it looks like to try and kind of really discover and vis, and visualize it. And you've got, like, to make gradual API changes, because if you start modifying the API, you don't even know what component is using that API. So that component is being used by another one. Is it being used by what application? So it's really hard for you to see what's, where it's being used. And are you going to break someone else by just, like, modifying the props, modifying the API of that component? Probably. That's not good.
4. Challenges of Onboarding and Deployment
Onboarding developers can be hard. Separating code for new developers would be better. Feedback loop and deployment process can be time-consuming.
That's not good. Onboarding developers can be, you know, pretty hard. You get a new developer in, and you give them this massive code base, and say, good luck, go swimming. Find the code. Figure it out. You know, what if you could just separate it out so that one new developer just has to worry about the code that they have to worry about? That'd be much better, right? And the feedback loop, it can go on for quite a while, because it's got to go through such a process, and when it finally makes it to production after everyone else has finished building what they're building, and maybe you deploy at this time, at a specific day, you know, once it gets deployed, so there's a long wait time, when really you just want to, you know, make one change, and just deploy it, right?
5. Challenges of Monorepo Tooling
Monorepos have no boundaries, leading to long build times. The problem is the tooling, not the monorepo itself. People want the ability to share components easily, have quicker build times, and own their own features. They also want consistent tooling and simple decoupled code bases. Bit solves these problems by allowing isolated and versioned components in a monorepo.
I mean, there are no boundaries, right? Everyone's working in the one code base. I mean, you could say, don't touch that folder that belongs to that team, but that's kind of like, pretty hard, right? There's no one policing that. So there is no real boundaries. And your build times can be pretty big, because you've gotta build, not just that one application, but every single application in that monorepo and all those components.
So, you know, do people actually like working with monorepos? Do they hate them? Do they love them? This is what I asked. And you know what? The problem is actually the tooling. The problem isn't the monorepo. Monorepos is a great way of thinking of doing stuff, but the tooling just hasn't helped, as Oliver says, or Garret says, crappy tooling. Even Brandon, he's like, loves the fact you can share code between apps and libraries, visibility, collaboration, consistency, ability to standardize, single-package versions, but he hates the insufficient tooling. This is what makes the experience bad, leads to bloated CI, and just loads of ad-hoc scripts.
So how can we fix this? How can we make this better? You know, what do people want? That's what we've gotta look at. What problem are we trying to solve here? What people want is the ability to share components. They wanna be able to easily package, manage their components. They don't want to have any version conflicts or break each other. They wanna have quicker build times. They wanna just build what they're building and like have that released and not have to worry about what everyone else is doing. They want team boundaries and ownership. So they wanna own their own feature, their own components, and like just work on those and leave everything else as if it like doesn't exist. And they want consistent tooling. They want all those components to be built with a similar kind of tooling so that they're all gonna build as they should be built and look the same across all those applications. And they kind of really, really want simple decoupled code bases. So they only have to worry about the code that they're actually going to have to worry about. So we're not asking for a lot are we?
Well, actually, welcome to Bit. Bit is a tool for component driven development. And with Bit, a lot of these problems are solved because of how Bit allows you to work with components. If you wanna work in a monorepo, you can work in a monorepo with Bit. You can simply have your base UI components, eCommerce components, and your store components or your application components all in the one monorepo. The difference is that every component is completely isolated and versioned. And therefore it's like its own little kinda repo, I guess. Every component is isolated, which means it can be used in any of those applications or any of those other libraries.
6. Component Isolation and Ownership
Components can be used in any application or library. Teams can own and deploy their own components. Bit provides documentation, a live playground, and Figma integration for components. It allows for easy visibility, discoverability, and searching across multiple scopes.
Every component is isolated, which means it can be used in any of those applications or any of those other libraries. Now you can also have a simple decoupled code base. So you can literally say, okay, I'm gonna separate it out because you know you're scaling, team's getting bigger, and you want teams to own features. So you can have one team, base UI, this is your repo and these are your components. You're in charge of this and build your components and deploy your components when you want to. E-commerce team, here's your components, build your components, deploy your components and just work wherever and whenever you want to. And then your applications, there could be another team that owns specific applications and they can deploy their components in their application whenever they want to. As Bit versions each component and isolates each component it can then be used in any of those repos, installed into any of those and basically used across any repo.
So here's an example, this is my base UI, code base and VS code and you can see on line two, I'm importing the button as a component from this actual repo, right? From the base UI repo, so it's importing it instead of using a local import because every component is, you know, version and isolated, I need to like basically install it as if it's its own package. So I'm installing this button and using it inside this team toggler component. Now in my E-commerce application or actually this is not an application, it's just a load of E-commerce components but in this E-commerce repo, I'm actually installing that same button component. So here I'm installing the base UI from the base UI repo, the button, the card, the heading and a few others are coming from a different repo, the one I just showed you and it's also installing some components from this particular repo, from the E-commerce repo. So I can install components from any repo inside any of my repos and workspaces. So this allows me to have team ownership. I have my base UI team owning those components, owning that repo, I have my E-commerce team owning those and then I've got my perfume store, my show store, my sports stores, different teams owning those applications. And at all times, I can see which components are using which ones. So I can see that the base UI is being used by the E-commerce and it's also being used by these stores and the E-commerce is used by these ones and I can see at all times, who is using who, who's depending on who, who's its dependents are.
Now, each component in Bit, comes with some documentation and a live playground. So you can at all times, look at a component, see what it does, read about it, figure it out by basically saying, this is the component I want and you can kinda play around with it and see, so I can change anything in this and it will change live. I can update that text, I could see what it looks like with a longer text, with the text break, what have I added a really long price, et cetera, et cetera. I can also embed the Figma designs, direct inside the documentation of my component, which means I can at all times, see what my component should look like according to what the design was and I can easily just click on that Figma embed and it will open the Figma file directly, where I can then further explore the padding and spacing that the designer created for that particular component. I can create different states of the components, so different compositions and see what the component looks like if I was to add something specific in there, remove it and change it, modify it, et cetera. And I can view the component props, so the API of the component, I can see that this component accepts a button text, which means I know I can change that text of add to cart to be whatever I want. I can change the price, but as I can see from here, I can't change the currency, so gotta work in dollars if I wanna work with this component. I can change the source and the alt tag for the image and I can change the text, so at all times, I can see what I have access to, what the types are, as well, and a description of what these props are gonna do. Now I can easily have visibility and discoverability of my components. I can search for a component. For example, I'm looking for a product card, I wanna see if the one exists, and I can basically just search and here I can see I've got an entity product or I've got a product card or I've got a price that's in the folder of products, so I can see I'm looking for the product card and I've also got a grid of product cards, so this gives me an idea of what is available to me. Now I can also search across multiple scopes or multiple reports, so here are my components. I've got base UI components, I've got multiple scopes in here like the e-commerce, the shoe store, et cetera, and I can just search across it and I can search for a button.
7. Component Search, Filtering, and Versioning
I can search and find the component I want, filter by specific dependencies, size, and labels. Once confident, I can install it into any of my components or applications. We create an environment component to define standards and tooling for all components. Independent versions allow us to choose which version to use and when to update. We can visualize the dependency graph of our components. We want to make components isolated and reusable in any app.
I don't have to worry about knowing if that button belongs to the base UI or if it belongs to e-commerce. I can just search and find the component that I want and I can see here, do I want a React button, a UI button, a TypeScript button? What kind of button am I looking for here? I can then filter my component by specific dependencies. For example, I might not want to use a specific dependency in my project or I might want one, so I can filter by, are we using Testing Library React, for example, because that's the one I want to build my tests with or I want to make sure that that's what's gonna be installed in my project. I can filter it out by size. Maybe I'm looking for a specifically small component and the same with labels and other stuff. I can now use my component anywhere. Once I'm confident that this is a component I want to use, I can basically use bit, NPM or Yarn and I can simply install it into any of my components or into any of my applications, no matter where they are.
Now, we can also have consistent and standard tooling for all our components. What we do here is we create an environment. Now, an environment is also a component. So, by creating an environment component, we can basically define the rulings and the toolings that we want for our components. So, we can have our prettier rules, our ESLint rules, our JS config, our TS config, our Webpack config, et cetera, et cetera, et cetera. And we can basically just create a component with all these standards that we wanna define. And then we just apply it to all our components as we're building those components. And then if we wanna modify it, we wanna add another rule, we wanna change something, we just do it once in the environment component and it will then get updated by all those components once we import it into that repository.
So, we can have independent versions for all our components. So here we've got our product card and we have the latest version, is version 1.0.13, and basically we can go back in time at any moment and we can see the state of that component, one back or 10 back or zero zero, whatever, and we can see what it would look like, what has changed, and we can decide what version of the component we want to use. Now, if we're working in a workspace and we were to modify the price component, for example, of the product card, then the product card will get auto-typed and a new version will auto be created because the price component that it depends on got modified. Now, if you're working in another application and another repo, and that product card gets a new version, you're not gonna break your app or anything because you get to decide if you want to use the latest version or not. Basically, it will tell you there's a new version. Do you want to import the new version? And you can say, actually, no, I'm not ready to update this version because you haven't finished updating the rest of the application to the new theming or et cetera, et cetera. So you always get to choose which version you want, when you want to update, and you can have multiple versions, different versions across different applications if that's what you want. And you can see what's going on at all times. So you can look at your component and you can see this product card component is using version 2.0.1 of the button. And you can see it's using the card, the heading, the image, the text, the available colors and the currency component and which version all of them are on. So at all times you can actually visualize the dependency graph of your component. So basically we want to reuse components in any app. This is what we're trying to achieve. We want to take the components out of the app and we want to make the components isolated. We want to make the components their own specific, like they want to basically say you're a component and you live wherever you want.
8. Component-Driven Development with BIT
Components should be isolated, versioned independently, and easily used in any application or component. Building with BIT simplifies component-driven development.
At the moment you're going to live in the base UI repo and the e-commerce repo or whatever, but that's not important. What's important is that you are isolated and versioned independently. You can be released independently and you can be installed into any application, any other component, whatever. You can be used all times very easily. And this is what you want. You want to make the component number one. This is what we call component driven. And this is basically what we all should be doing. We should be building component driven webs, component driven apps, component driven everything. And building with BIT is going to make that easier.