 Hi there, in this video I'm going to show you how to build a UI library using React, Irwin CSS, and Storybook. We're going to create four different components for this library, which will be a button component which will be served in three different variants such as solid button, outline, and ghost. Then we're gonna have an input component which will be useful for gathering user information such as a plain text, password, numbers, and also dates. We're gonna have also a text component just for displaying some basic text in different styling. We will also have a layout stack component which will be useful for applying a vertical layout to our screens or containers. And finally, we're going to put everything together by constructing this login form which will use only the components that we have defined above. So without further ado, let's get started. Okay, let's start by creating a new React project. We are gonna use VIT for creating our React library. So let's run yarn create VIT. Let's name this project simple UI. Select React as a framework, variant type script. Let's see the inside simple UI and install all the dependencies by running yarn. Okay, once done, we can start up the server. And it should be listening on the port 5173. Let's see if it's working. Yep, it's working correctly. Okay, next up will be open this project on VS Code. So let me select import UI, open up. Okay, so this is our initial project structure. First thing that we like to do is to initialize a Git repository. So let's make a first commit. Let's open up the source control. The commit message I will use the co-pilot hints. And let's go into commit this. Great. Okay, next up, I think we'll be setting up Preter for automatic formatting our files when we save. To do that, we are gonna need a VS Code folder where we are going to define the setting.json inside. We are gonna paste this configuration right here. As you can see, as soon as I save the file has been formatted automatically. Okay, let's try making some initial changes to see if it's working correctly. Let's remove this, also this stuff. Let's try to define a paragraph which say it works. And as soon as I save, we can see that Preter is working correctly. I think we are gonna have to restart our dev server. And yep, it's working properly even though it's all the way on the left, but this should not be a problem. Now, I'm going to remove all this file because we are actually building a library and not an application. So we don't need any of this file except for index.css. And like for showcase how our application will work, we are gonna use Storybook that we are going to implement later. So let's remove all this file. Okay, so let's commit this stuff. Perfect. As a next step, I would like to configure the tsconfig. What we are going to do is adding a base URL, which will be the current folder. And also define some path analysis. In this case, we can apply the suggestion given by Copilot. And this is needed for avoiding having like absolute paths with many dots inside. As a next step, we are going to update also the ESLint file. And we are gonna apply some custom rules. We are going to replace this with another configuration where we basically shut down some ESLint rules. Great, so okay, let's commit this stuff. Okay, now let's start by scaffolding our library structure. And we are gonna need some different folders, one for storing our components, another one for storing some material function. And finally, another folder that I will call example, where we are gonna store some kind of screen. Okay, inside this components folder, we can start by defining our first component, which will be a button. I'm going to define the index.sx. Great, let's define our component. And actually, this will be a HTML button element. Most important, inside the component folder, we're gonna need to define another file called index.sx. So we're gonna need this file for like collecting all the export for relative imports. Yeah, at this point, we are gonna need to install Tailwind. So let's go to Tailwind.css.vit, which is a guide basically that explains how to set up Tailwind in a VIT project. And so we can start by installing Tailwind.css, so all the dependencies. So we are gonna need these three dependencies first, so this yarn add. And while it's installing, next step will be generating the Tailwind config file that we are gonna do in this way. Tailwind.css init-p will generate the Voss.css config.js and also the Tailwind config. So third step is like defining where our Tailwind classes are used. So we can just put the source folder to tell Tailwind to look out for Tailwind classes inside this, all this directory right here. Next step will be adding the Tailwind directives inside the index.css. So let's go here, remove everything. Actually, I think that I didn't copy this out, great. If we go back to our button and trying to find class name, we should have the intelligence enabled for Tailwind. As we have seen before, we don't have any application entry point for this project because this is, as I said, this is a library. So we are gonna install Storybook for showcasing our components and examples. So next step will be first, starting by committing this stuff. Let's go here and run npx-storybook init. Okay, once Storybook has finished completing installing, it asks us if we want to add some ESLint rule to enhance our dev experience and yeah, we can install it. Okay, so as you can see, Storybook has launched automatically. We can skip all this stuff and I guess that it adds so many files that we don't actually want. So we can safely remove this folder, stories, and what we can do is like updating the main configuration of Storybook. So here you can see how Storybook find out their stories defined in our code base. So it basically go inside the source folder and start to looking for all the MDX file or it search for all the file that have the .stories.js, .jsx, .ts, .tsx file extension. Okay, since we are using Path Isles in our code base, basically we have to specify a special configuration to enable Storybook to work properly with Path Isles that we define the ts-config. In order to do this, we are going to add this configuration right here that I will just paste and it's basically this VIT final property. So basically we are saying to Storybook to go in the ts-config file and search for all the Path Isles that we have defined. To make this configuration work, we have to install a special function, which is this ts-config Paths. In order to do that, we need to install a new dependencies, which is yarn-add-d which is called VIT ts-config Paths. So let's add it to our project. We should be able to add a new dependencies, which is this function ts-config Path from VIT ts-config Paths. So we need also to import Path from Path. This is the native module Path, which is used to resolve Path in our project. So, okay, this is the first configuration. We actually need another configuration under the preview.ts file. So basically here, we need to link Storybook to Tailwind CSS and the way to do this is to import the index.ts file, which is located under the source folder. And if you recall from that, it basically contains all the Tailwind directive. Great. Okay, so now we can start by defining our first story. Let's go here and define a new file called index.stories.tsx. And as you can see, inside every component, we are going to define the index.tsx file, which is the implementation file of our component and a separate story file. So, first thing that we need to do inside our stories is to import some type. We're going to need meta and story object. Then we're going to need to import our button component. Then we have to define an object called meta, is of type meta with the type of component button. And here we are going to define a title, which will be under components button. We have to specify the component itself, specify some parameters, for example, the layout. We want the layout to be centred. And finally, the tag property where we set auto docs. This is needed for generating a page called docs. Okay, from that, we're going to export this default meta, since this is needed. And then define a type story, which will be equal to the story object of type of meta. Actually, we have to import this. And for define a first story, so here we define a first story, where we pass as children of our button, let's say, the string, click me. So now what we need to do before checking if it's working properly is going back to our button component, and taking in input all the props that a button element expect. In order to do that, we can do component props of button, access into all these props. On in a type of notation here, and then spreading out these props. In this way, we access all the props of the button. And from here, we are able to basically specify, we have access to all the possible attribute that a button element expect to take in input. Okay, so let's try to run storybook at this point. Let's run your storybook. And you can see that tailwind is working properly. The text is blue. We have no custom style since tailwind by default strip out all the default CSS based style. And we can see that we have all also these docs auto generated page, where we can define all the different props that this button takes in input. Okay, so you can see the string click me is not rendered. This is because we are actually define custom children here. And we can safely remove this and basically use a self auto closing tag. And if we go back here and refresh, you can see that now we can put everything here like hello. And it's working fine. Great. Before moving in, let's commit all these latest changes. And also this one. And now it's time to talking about how we are going to handle all the styling part for our components. Ideally, we want to use tailwind for applying custom style to our component library. But actually, since we are building custom library, we want to we are aiming to creating component similar to, for example, chakra UI. Let's take, for example, the button component. You can see that every component accepts different prop, which enables us to define sizes, for example, small, medium, large, different variants for our button, different colors, and everything is done by defining props. So we want to achieve the same result. In order to achieve this, we are going to need to install three libraries, which are CLSX. CLSX is basically a library for constructing class name string conditionally. Then we are going to need tailwind merge. And finally, we are going to have a library called class variance authority, which I'm going to show you here, class variance authority, also named CVA. And basically, all that this library does, it's permit us to define different variants for our component. So basically, here, we define some of the props that our component takes in input and apply to these props, particular styling. For example, here, we are saying that for a button component, we want a prop name in 10. And this intent prop can have the value primary, or secondary. And if we apply primary, we are going to apply this tailwind style. And if we have secondary, we are going to apply this one instead. We are going to have different props. For example, here, we have intent, but we have also sizes with the value small and medium with the relative styles. We can also compound these variants. For example, if we have a primary hinted with the medium sides, we want to apply the tailwind class uppercase to our button component. And we can also define some default variants. Okay, so at this point, we are going to need a function that we are going to define inside the utls folder. So let's start by defining this .usx file. And so what we are going to do here is import CLSX and also the plus value from CLSX. Then we are going to need to import a tailwind merge from tailwind merge. And after that, we are going to define a function called cn that what it basically does, taking multiple classes from class value, and then basically apply a tailwind merge and then apply a CLSX. So what it basically does is to apply the CLSX function to all these classes. These classes are going to be defined inside our class variants authority and merging them together. Let's see how does it work. Let's go back to our button and let's define some button styles. We're going to use the cva function import cva from cva class variants authority. The first parameter is going to be the default style that our button component is going to have. So for example, we want our button to be full width. Okay, actually, before I start implementing our style for button component, we can go inside the vscode folder, open the settings.json and define a new property. Let's paste this here. So what this property does is basically enable the tailwind intelligence inside the cva function. So now if I open up string quotes, I should be able to access to all the tailwind classes. Great. As I was saying before, this cva function permits us to define different style for our components. The first parameter in this case will be the default style for our button component. So let's start by saying that we want a full width and we want our button to have some rounded border. We want the font to be semi bold, having no outline when it's focused. And finally, when our button is disabled, we have no cursor, cursor not allowed. And so this first parameter is so is the default style that our button component is going to have. Then we can define different prop or variants, different props that our component is going to accept in input. So actually, we want to define a prop called variant, which could be solid outline with some kind of border. Let's remove the color from here. We want also another variant called ghost, where we are applying the transition colors and a duration of 300. We want also another prop called size, where we define small with a px of four, py of two, and text set to small. And let me just copy the other two values, which are medium and large. And also we are going to accept a color scheme, which is going to accept as value only the primary value. Okay, so let's define also some compounding variants. So compound variants basically are applied when multiple variants start to combine one each other. For example, when we add a solid variant with the color scheme primary, we want to apply the bg primary 500 with this over styling. And the same is for the outline button of the offer the ghost button. Actually, you can see here that we are using primary, which is not supported by tailwind in order to do that. Let's go ahead inside the tailwind config and extend our team configuration. And let's add a new colors called primary. And let's define our primary color to be blue. Actually, for having this color, we have to import color from tailwind CSS color. So our primary color will be the blue colors provided by tailwind CSS. Great. So if we go back inside our variants, you can see that now the extension is working properly and give us the proper suggestion. Finally, I'm going to apply also some default variants. So if we don't specify any kind of custom property that we define above, we're going to apply solid variant, medium sides and the color scheme to primary. Okay, then at this point, what we can do is to first off extend our button props by using the variant props of type of button style. These variant props should become from the class variant authorities. Great. So now our button props should receive all this new custom prop that we have defined here. For example, if I go here, you can say that now I can access the variant prop, I can access the sides and also the color scheme. Once we have all of this, here we are missing a common. Let's remove this class name because we are going to use the previously defined function cn and this cn function is going to use the button style that we define above and passing an object with the different props like variant, sides, color scheme, and also we want to extract the class name prop since we want to potentially update our button component by defining custom tailwind classes from the consumer point of view. Great. So if we go back to the index stories of the button component, you can see that inside the argument that this button takes in input, we should have the variant and you can see that here we can accept solid outline or ghost. We are going to use solid. We can specify a side which should have a small, medium, and large. Let's define a medium and also we should have a color scheme which can be only primary. If we go back to our storybook, you can see that everything is working fine. So our component has a blue background and based on the variant that we set, in this case solid and the sides of MD color scheme primary, we can see that is rendered correctly. Actually we have also the default story that we define which is using the solid variant that we defined before. What we can do now is instead of having this default story, define specific stories like for example one for the solid variant, another one for the outline variant, and a final story for the ghost button. So if we go back to storybook and let's go ahead inside the docs page, we can see that we have all the different button, the solid variant, the outline, the ghost button. You can see how the transition is applying smoothly, also for the outline. We have the three different stories applied for every variant of this button component. Great. So actually we are missing, like to make this component library proof, we are actually missing one property which is the ref prop. In order to have the ref prop, which should be like be able to access here, we have to use the forward ref function provided by react. This forward ref function accept two type parameters. One is the props, the element that we are working on, in this case an HTML button element. And the second is the props that the component accept as input. So this forward ref accept an input function which is the element. So it's basically pretty much the same. We have to return this button here inside and inside the function that we are defining. We are gonna have all this stuff that we extracted here. We can remove it from here. This part can be safely removed now. And also this. Okay, as you can see now is formatted nicely and is much more clear. After the comment, we have a second argument, which is the ref, which we can pass here. Great. Now is our first component is pretty much ready. We have all the variants. We have the ref prop and we can move to our second component, which will be a text component. But before moving in, let's commit this stuff. Great. So let's now define our second component, which will be the text component. Let's define the index.sx file. Okay, so let's start by defining component. We will name text. The text component, we can start by defining it as a span component. Then we will need all the props. So type text props equals to component props of a span. Let us spread access these props here. Text props and passing it inside the span element props. Great. We can define all the class variants that we want to apply to our text component. I already prepared this. So let's just paste it here. We have to import our cba variants authority. Let's take a quick look at this tile. So we apply for every text component a full width. And we define the following props, the emphasis, which can be only low, where we apply a text gray 600 and a font light. We apply some the prop sides, which is basically mapped to a wing class to manipulate the sides of the text. We have the weight prop property for aligning the text and to Boolean prop for applying underlying or italic text styling. And by default, we apply like the base font sides, and we align the text to the left. So to accept this, we have to access the variant props of type of text tiles. We have to access it here. Great. Our text is now should be ready. Let's define some story or index dot stories dot sx. And here I will just copy some stories that I already prepared. So we basically define the meta object, which put the text inside the components of folder in storybook. Here we define the default, a default story with a long string inside. So let's go back to storybook. And let's see if this test component is rendered correctly. Actually is a rendering text because we have to remove this and applying a self closing tag. Our text component is working fine. We can actually go here, put our string hello world. Okay, so at this point, this component is missing the forward reference. Let's do the same thing we did for our button component. So forward ref pass here HTML span element and also the text props. This will take an input function, which should be this one. We don't need also this text props, I guess. And here we should be able to access the ref can then spread here. Great. Actually, we are missing an important part for this text component, which is the s prop. What is the s prop? For example, we want this text component to be rendered as an h one or h two as a paragraph as a span. Currently, we are rendering all text component as a span, but we want this to be dynamic. In order to provide this feature, we have to define first some utility types, which I'm going to define inside the utl folder. Let's create a new folder inside utl school type. And here, let's create a file name index dot ts. Okay, inside this file, we are going to define some type that will enable us to passing the reference to the text component and accept in input a generic HTML element to pass as the s prop. I'm going to define some type. First, we need the type props off, which basically extract all the props of a particular component. Then we define another type called s prop that add the s property to the prop that our component takes in input. Then we need another type, another type, which is extendable prop, paste everything here. Now, these are a little bit tricky to understand. But basically, what we are doing is to define some types that accept in input a generic element type. And from this generic element type, we extract all the props that this element takes in input along with the s prop. And also, we should be able also to take an input the ref prop. So they are a little bit trigger, but I suggest you take a moment to understand how they work. So let's back to our text prop. What we are going to do is to remove this old type text prop and define a new one, which is also named text prop, but we'll take a generic type parameter, which will extend a react element type. This will be equal to polymorphic component props with ref where we passed the generic type C, which should be an element type, and also all the variant props that we define above. So we have this text props type. And we also need another type name text component, which is equal to a generic type argument, which also extend the react element type, which by default is a span. So every component that does not define the s prop will be rendered as a span. We're going to define the props, which are text prop of C. We are going to return a react react element or null. This point, what we need to do is to apply a type annotation to our text component to be equal to text component, then remove this type argument from the forward reference, because now we have to apply a generic type argument inside the forward react function. Here we have to define the element type, which should be equal to the span. So these props will now be type, we have to define a type annotation, which will be equal to text prop of C. And also this ref will be equal to morphic ref of C. At this point, we have to extract some of the prop that this text component takes in input, including the s prop, and also all the variant properties like align, type, emphasis, metallic, underline, wait, and also the class name. Now what we have to do is extract a variable called component, which will represent the component that will render this text component. So it can be s or if it's not defined will be a span. And then we can use this component inside the rendering function. Okay, here also we have to define our class name, where we pass the cn function and pass the text style inside. We have to pass all the variant, wait, emphasis, this, metallic, underline, align, and also class name. Great. So we should have everything set up. And finally, all the remaining props, which we should take from here. Great. As you can see, if we see this error, I was not able to understand why TypeScript was throwing this error. The way that I fix this for now is to expect a typing error. But for now, we can leave it like this. And yeah, now our text component is ready to accept all the variants that we define in the text style. And also, like we can render this component by using custom HTML element, or if we don't specify anything, we use the span element. So if we go back inside this index.story, you can see that now I can pass this as and pass, for example, h1. If we go back to storybook and hit refresh, if we open up the inspector, this component now is rendered as an h1. This enable has to build bullet proof components. Okay, before moving in, let's commit our latest changes. Okay, so now we can create another component that I will call input. So let's define the implementation file. Let's export this input component. Obviously, this input will use the input HTML element. We can remove everything here and use self closing auto tag. Let's take all the input props, component props of input. And then let's spread it this props here. And say input props. And go here, pass this props. Great. Let's define also some basic styling. So let's import here tba from class variants authority. These are some basic styling that we can use for our input text. So we set full weight border, border gray, rounded border. Yeah, some basic styling. Okay, at this point, what we need to do is to get the class name and actually extend this input. Let's define it here. And let's take the variant props from type of input style. Let's import this from variant props. Great. So here, you can define our class name by using the cn function, passing the input styles. We're not defining any particular variant for this component. We don't have to pass anything inside the input style. By default, let's set this type to text and remove the autocomplete. Okay, we need also to apply the forward reference. So here we are going to change the input element and here input props. We're going to copy this out here inside. We can remove also this type of notation, get the reference and pass the reference here. Great, our input component is now ready. So let's define some stories. And I'm going to just paste some stories that I already made it. So as always, we define our meta object. And here I define like some basic story for our input text component. For example, here, we are defining an input text here, an input password, input number, and also input date. We have our new input component. This is the input text variant. This is the password example, number, date as well. And in the docs page, we have all the different variants put together in the single page. Great, we're going to use these components like button input text to create a login for to put all these library components together and see how they works. But before we do that, we actually miss other components. Let's first commit everything. What are we missing right now is some layout component. So let's create a new folder layout here inside a new folder as well called box. I would like to define stack. Let's define the implementation of box. So let's define our box component. This is actually, we can remove this and using a self-closing tag and define the box props to be equal to component props of div. Here, extracting the props, all the various props, and spread it out here. Great. Then we do have to forward the reference and here define the HTML div element, also the box props, and pass the reference here. Great. This will be our box props. We don't define any kind of variant because it's a layout component. So does not make any sense to have particular styling for this component. But actually we are going to leverage this box component to define a new, this other component, the stack. So let's define this implementation file. So let's name it stack. Great. Let's remove all this thing. And we are going to use the box with self-enclosing tag. Let's define the stack props which will be basically equal to the box props because they are pretty much the same. Correct. We have to first export this type. Great. So now we can update the import and pass it there. Stack props on stack props, writing all the props here and passing it right here. Actually, we are getting this error here because the box props are missing their reference. So we have to use component props with ref, which we can import from react. And now the error has disappeared. Let's define the class name. So we are going to use the chen. We are going to pass, for example, a flex and flex column with the item that to start. So basically a stack is when every element is stuck one after each other. The second argument will be the other class name that we are going to extract from the list of props. Great. The stack props can be lived like that. Let's define a new story, torus.sx. Let me just copy our initial configuration. Here we can start leveraging the path aliases, but for doing that we have to start exporting all the components from the main index file, another main index where we export everything, go back to our story, import our stack component. This is the same configuration we applied for the other stories. And now let's define a particular story to see how these stack work. So let's define a story. We have to define a custom render function to make it work. So here we can take the arguments. Let's declare our stack component, which will take all the arguments. And let's define also some class name like a theme song up, a little bit of padding, and also a bg gray 400. And inside this stack we can define multiple box which are going to, we have to import this. And here we are going to define for example a width of 100 pixel on 8 of 100 pixel and at the ground of blue 500. Surely we can start and close this. And let's redefine box. Let's copy this out. Let's make the second box red and the third one green. This stack will contain this three box of 100 by 100 pixel. Great. Let's go back to storybook and we should be able to see our stack under the layout folder since we wear this under layout slash. And this is our stack component. You can see that the three boxes are stacked one each other. Okay then, let's commit everything. Let's go back to our explorer. Now we have all the components that we need for this library. We have button, input layout and text. We can make our first example which will be a login screen where we are going to use all of this component. And this example will be available on storybook as well. So let's define our login form. Okay, so let's start by creating this login form. Let's start by defining a parent box. Great. So let's import our box and let's add some horizontal padding and vertical padding. Also some border and border gray set to 300. Great. So now we are going to use the stack component. Let's start by defining a text component. Import it from text from components. This text will be in this case an H2 and we'll have a weight of bold and also will be centered aligned and a size of 3xl and also a custom class name that the marching button to two. And inside this text we are going to add the login text. So under the login text we are gonna have like a subtitle which is going to say please enter your credentials to login and this text will be a span. We'll have the emphasis set to low and also the size set to small. It will be centered aligned and also have a class name of margin bottom 8. While we are doing this we can start by defining also the story. We can just paste it. Actually we don't need to specify anything inside the main story that will be named login. Okay so let's see how this is coming. It's coming as expected. We have our login title and also subtitle. So let's add some field. Let's add a text which say user username and this will be rendered as a label. We'll have an html4 username, size of small, weight of medium and also a class name to set the margin bottom back to 1.5. Okay now let's use our input text component. This could be self-enclosing. Let's import it. It will be type of text, an id having username, placeholder set to username and also let's define some margin bottom set to 4. Great, a password, the password type. So we define first a text label and then an input component which will have the type set to password. Let's say how it's coming. It's coming great. Finally we are gonna have submit button. We'll say login. Let's import it. This will be of type submit. We'll have a variant set to solid and a class name or margin bottom set to 10. If we go back to storybook you can see that this input text is not setting margin bottom to apply some spacing to the below password text label and this is because if we go inside the input component we are not passing the class name inside the input style. We can actually doing now and now it should working properly and great. Now we have our login screen that we build entirely relying on our library and set a username, a password and also we have our submit button here. There you have it. We actually build our input library. So let's commit these new changes. So the final point of this video will be showing you how to make this library a standalone package that we can possibly push in a package registry like npm or yarn and so in order to do that we have to make some tweaks on the various configuration file that we have. So first off let's head into the vit.config.ts. So inside here we need first to define the property result where we basically define our path aliases. In this case our path aliases start with the head symbol. Really we need to import a path from path and here do path.resolve and so basically resolve all the imports that start with the head symbol inside the source folder. The second configuration is the build property. We are going to define the lib configuration where we basically define the entry path.resolve directory name. Here we are going to use source components slash index.sx that means that the entry point of this library will be inside source component and basically all the stuff that we are exporting inside. Actually here we are missing all the components from our layout. So let's do it in this way. So after the entry point we should specify a name for this library. In this case we can name it simple UI and then specify the file name for the import which will be simple dash UI. Actually this is file name like that. Great. Second option will be the roll up option where we basically define all the dependencies that we don't want to bring inside our package. We have to define also the output where we define some globals like react will be react and reactdom will be reactdom capitalized. Great. We have actually we need to define also a custom plugin which is named bitplugin DTS. Let's go into install it. So let's clear the console and run yard add dash d bitplugin DTS. Great. Now let's import this plugin right here. And as a last step let's define this DTS plugin and we have to pass the rollout types that to true. Great. What this plugin does basically is generating the index.d.dts file which is the file which contains all the type for all the components and function that we are exporting. Great. So this was for the bit configuration. Last step will be going into the package.json. We have to define the files property set to dist. Actually set to dist. Great. Then specifying the main entry point for this file which will be this simple ui umd cjs and then define the module improvi.js. Then we need to define some exports the current folder where we are going to have as import this simple ui.js and as required we are going to have this simple ui dash umd cjs. That should be it. Now if we go here and we run yarn build which should try to bundle this library but actually is not able to resolve the entry model search components.ts because actually its name is um we have to go back here and name this as tsx. Now it should work here build. If you go take a look at tower explorer we can see that we generate this folder which inside contains some file including the simple ui and simple ui umd. Basically this umd file will change based on the environment of where this library is being imported. It will be transformed into common js or the new sts module. We have all the types declared inside here. Actually here we have also this vit.svg. We actually don't need this because so we can remove the public folder and we can actually remove the index folder index.html since we don't need it anymore. So let's run another build and let's see if it is cleaned up. Yeah you can see that now we don't have that svg anymore. Great so this will be like shipped as our package library and we can publish as I was saying in a registry to be used by other user or by us for making our personal project. Great let's commit this stuff and there we have it. That was pretty much it for this video. I hope that you find it useful to understand what's our desktop required to building a library. As always if you like this video leave us a thumbs up and if you have any kind of question feel free to reach me out in the comments and as always we will catch in the next video.