# π‘ Autogenerated Component Libraries & Theming ## π€ Context Recently, @itexpert120-contra.near completed a component library for @build.sputnik-dao.near, which you can find at [nearbuilders.org/library](https://www.nearbuilders.org/library). It's essentially a fork of [mob.near/widget/N.Library](https://near.social/#/mob.near/widget/N.Library), but it consists of all VM.required modules rather than Widgets. This comes with some advantages: * Pages + components seem to load much faster because VM.require's share the [current VM instance](https://github.com/NearSocial/VM/blob/d21147330def9eae4ba1874cced0773eccfedde2/src/lib/vm/vm.js#L2209), rather than [creating a new one like Widget](https://github.com/NearSocial/VM/blob/d21147330def9eae4ba1874cced0773eccfedde2/src/lib/components/Widget.js#L157). * All components are able to be referenced from the same ["components"](https://github.com/NEARBuilders/gateway/blob/main/apps/builddao/widget/components.jsx#L34) file, so you don't need to know exact paths -- which is a more familiar pattern for component libraries. This could probably be improved even more using @mattb.near's Loader? * Functional components are really clean to work with, for example: ``` const { Button } = VM.require("buildhub.near/widget/components"); return ( <div> <div className="d-flex align-items-center gap-3 mb-3"> <Button>Normal</Button> <Button variant="primary">Primary</Button> <Button variant="outline">Outline</Button> </div> ); ``` **Note**: VM.require modules do not allow hooks or manage state, but sometimes a component in the library needs state. To fix this, we simply return the widget as a module, like [we do for Post](https://github.com/NEARBuilders/gateway/blob/dfb2ff4cb016f38baa9a6df5bdc74842c86648d5/apps/builddao/widget/components.jsx#L34). Other component libraries: [Common Components Library](https://near.social/manzanal.near/widget/CommonComponentsLibrary) @manzanal.near [NUI](https://near.social/#/nearui.near/widget/index) [DIG](https://near.org/near/widget/DIG.OverviewPage) ## βProblem Updates to any components in the library means needing to update the Library widget, too. Doing the former without updating the latter leads to inconsistencies and poor documentation. Multiple projects maintaining their own component libraries could potentially be cumbersome too, especially when considering the underlying components are mostly the same aside from theming. ## π Solution All components being referenced from the same module (buildhub.near/widget/components) means we already know the contents of our library. We have a build step during [bos-workspace](https://github.com/NEARBuilders/bos-workspace/blob/main/lib/build.js) that could potentially be used to update a component library JSON. bos-workspace also has Typescript support -- Types defined in code could be used to define the props available for a component. Metadata for individual components could be used to populate the rest of the data and would lead to parity between library items + [WidgetSource](https://near.social/#/mob.near/widget/WidgetSource). Also -- theming can be applied via classNames from a parent widget -- so component libraries that are exactly the same aside from CSS should have this CSS extracted to parent, so there is only one shared component library. @rambo-dev.near had some ideas regarding a "ThemeProvider". It would be nice for builders if a Library was a default tool readily available whenever developing ## Feedback Any feedback or thoughts? Anyone want to work on this? This [repository](https://github.com/NEARBuilders/devs.near) is hooked up to deploy to devs.near, we could coordinate here or always open to suggestions. #build #idea