The Gold Mine of UI Frameworks: BaseWeb
Tags: react, css, typescript, ui
Published: 2021-02-15 15:55:29

There's a lot of UI frameworks for every Javascript framework out there, they offer different things but today I'm going to present you with the Basewebui framework 'cause for me, it was like found A GOLD MINE.
### Some Context:
I start this "_new_" JS frameworks journey with the Vue.js framework, after this I try Nuxt.js (it's the Next.js of Vue.js), and I love it, then I've tried some UI frameworks with it (**BootstrapVue**, **Vuetify**, **Antd**) they're all fantastic.

But I always got low-performance issues, and when I test different websites with different **UI frameworks**, with Lighthouse or PageSpeed Insights, the results are terrible 60, 70 maybe an 80 with a lot of effort. And then I accept it..., and to be honest I have 2 o 3 websites on production with very low performance 😢.

![Low-Performance Screenshot](https://i.imgur.com/a2oJn5Y.png "Low-Performance Screenshot")

After this, I learn React.js, after using it for a while I enjoy the **tailwindcss/react** way. But honestly re-inventing components that almost every UI-Kit or UI-Framework has out of the box, it's not a great thing (_at least not for me_).

>When you want to build complex interfaces, and you are working alone it's better to have a suite of components, and it's better if you can customize it, that's the reason that I love **tailwindcss**, 'cause it's very customizable, but it's a little hard to handle for me.

After all, this and like with Vue.js I try different UI-Kits with React like **Antd-REACT**, **ReactStrap**, **Semantic UI**, and again **THE SAME LOW-PERFORMANCE ISSUES**, and I was like...maybe

![This is who I am](https://media.giphy.com/media/h7vNrcyrglScZOItBE/giphy.gif)

> _I'm a low-performance websites guy. 😭 ... I'm not that good with performance ... maybe this is not my thing_


And just for causality, I found **BaseWeb UI Framework** ...
First, it's from **Uber** folks, and (at least for me) means _Quality_, has a lot of components, it's very flexible, it's very customizable, very performant and for more reasons, I feel I've found...

### A GOLD MINE 🥇.
I try it..., and honestly, it was a little **confusing** at the beginning 'cause' they're using a "_particular_" CSS toolkit to manage the CSS of their components which is **Styletron** and If you read about _Styletron_, they're focusing on **Performance**, the particular thing among others **UI-Frameworks/Toolkits** (_Styletron specifically_) generates styles only when is needed.

> - This concept is also known as the **critical rendering path**.
> - Styletron has a CSS in JS architecture
> - Styletron is component-oriented styling

So, let's try Baseweb :)
### Setting-Up Styletron ⛏️
We're going to use Next.js because it has a lot of utilities for production out of the box, and we want to test the performance of the application in a production scenario (for example this website need's to be SEO friendly).
1. First you need to know that Styletron works with **any** JS framework or even Vanilla Javascript, but **BaseWeb** it's only for **React.js** you can check [how to setup Styletron with react](https://www.styletron.org/react) but we're going to check [how to setup Styletron with next.js](https://www.styletron.org/getting-started#with-nextjs) and then we're going to integrate Baseweb UI.
  - And you may like, Wait, what? ![wait-what?](https://i.imgur.com/jKbHZYL.gif)
  - Why we are setting up Styletron?, This post is about BaseWeb UI. ¿? ... well
  - That's because like I mentioned before, BaseWeb uses another CSS toolkit to manage the style of our components, and it's better if you understand how it works.
  - (_BaseWeb has a [getting started](https://baseweb.design/getting-started/setup/) section but in this case, we are going to set it up from scratch to understand **how it works** in depth_)

2. With this clear now Create the next app with Styletron example app provided by Styletron Team **just run:**
  - `yarn create next-app --example with-styletron nextjs-basewebui-app && cd nextjs-basewebui-app && yarn`

3. Then run `yarn` or `npm` in `dev mode`, This package sets some configurations into **_app.js**, **_document.js**, and adds a simple example in the app/index.js page of how Styletron works.
  - Finally, **styletron.js** is the file that StyletronProvider uses to inject **styletron-engine-atomic** and **styletron-react** in our app
  ![Initial structura + view](https://i.imgur.com/MhZ2g9T.png)
  - Inspect **pages/index.js** and you got something like this:

`import { styled, useStyletron } from 'styletron-react';`

  - Both are packages that use CSS-in-JS architecture, and you can use _useStyletron_ as a hook and set styles into JSX like the example.

`  const [css] = useStyletron();`

`   <p className={css({ fontSize: '32px' })}>Styled by hook</p>`

### Refactor and Add Typescript 🔧
> We are going to change the base structure of the project for a convention, and we are going to move to ** Typescript ** which is easy in this case, but you can work with plain ** JS ** if you prefer, We're going to move all the next.js workflow into **(src/)**  directory, and we will add _typescript_.


You can follow the **steps**, **copy**, **fork**, or **clone** the necessary files in the [repository at this point](https://github.com/irvv17/Nextjs-Baseweb-Boilerplate/tree/9c92727a89a2a789d55873a5c057949b123b4106).

After moving the workflow into the **src/** directory we are going to add:

- Typescript
- Jest
- ESlint
- Prettier

Feel free to check the [package.JSON](https://github.com/irvv17/Nextjs-Baseweb-Boilerplate/blob/9c92727a89a2a789d55873a5c057949b123b4106/package.json) if you don't how to set all these packages


* Then configure **ESLINT** with **npx eslint --init** command.
* After this we will add prettier, this is much easier just run **yarn add --dev --exact prettier** and create a **.prettier** file.

However, both files are here: [.prettier](https://github.com/irvv17/Nextjs-Baseweb-Boilerplate/blob/ec0fbe9a0d033aedd0a806ff03653cb9fc71d4e6/.prettierrc), [.eslintrc.json](https://github.com/irvv17/Nextjs-Baseweb-Boilerplate/blob/ec0fbe9a0d033aedd0a806ff03653cb9fc71d4e6/.eslintrc.json)

>**Now** we have a regular next app with **Styletron**, but the main source is into **src/** folder, and we added **TS** and **ESlint** with prettier, This is the structure of the project at this point:


![structure with TS](https://i.imgur.com/8K7vVz5.png)

The changes into **src/** files are just about typescript, you can check it [here](https://github.com/irvv17/Nextjs-Baseweb-Boilerplate/tree/50a53a6428433160df3ea4afb97609e65610bab2)...
After these changes, if we run **yarn dev** we will get the same view that we've sawed before, 'cause we just change **JS** for **TS**.

![TS structure plus view](https://i.imgur.com/eNS65ur.png)

Now let's add Baseweb to our project, this will be easy, 'cause we have the **_heart_**❤ of Baseweb in our app (which of course is **Styletron**).

### Setting Baseweb UI framework 🛠️

1. First, we need to add Baseweb dependencies, this is pretty easy just run `yarn add baseui` now were going to set the _baseui_ package in the whole application, this is pretty simple, 'cause we ran the Styletron boilerplate first, so we already have that configuration into _**app.tsx** file.
2. Now open that file and add **BaseProvider** (you can check it in the official documentation too) but basically, **Styletron** and **Baseui** have **_separated_** providers, so we are going to wrap **StyletronProvider** into **BaseProvider**, and Baseui will use the StyletronProvider.
  - That's the reason that we start with just **Styletron**, now you can understand how baseui uses the CSS-in-JS.
3. We need to import **BaseProvider**, and a **theme** (were going to talk about themes later), after import the file we need to wrap **StyletronProvider** into **BaseProvider**
  - (you can check the [official documentation](https://github.com/uber/baseweb#usage) and it's the same thing, but our Styletron provider value is separated)
![_app.tsx with the baseui and styletron provider](https://i.imgur.com/uj2pbfu.png)
  - If you run in dev mode, the result is the same 'cause you are not using any baseui component yet.[ you can copy this file here](https://github.com/irvv17/Nextjs-Baseweb-Boilerplate/blob/9c06b3d781f19a8d5e0982a4d4279332639f11fc/src/pages/_app.tsx)

### Using our first Basewebui component

1. Now we can import any component of the baseui package in our pages or other components, let's add a Navbar in our **index** page.
2. I'm going to create a **NavBar** component and save it into the components directory
3. Copy the example of a navbar component in the [official documentation](https://baseweb.design/components/app-nav-bar/#examples) into our **NavBar.tsx** file ([You can copy this file here](https://github.com/irvv17/Nextjs-Baseweb-Boilerplate/blob/79f197771f232c5d3fcd63e7ebed51a02f61a30c/src/components/NavBar.tsx))
- ![NavBar Component](https://i.imgur.com/AKkFVe5.png)
4. Import the NavBar component into the Index page ([You can copy this file here](https://github.com/irvv17/Nextjs-Baseweb-Boilerplate/blob/79f197771f232c5d3fcd63e7ebed51a02f61a30c/src/pages/index.tsx))
  - ![Index with NavBar Component](https://i.imgur.com/w9RsIlz.png)
5. start with `yarn run dev`, and Voilà! a beautiful mobile-first Navbar appear 🤯
  - ![Index with NavBar Component](https://i.imgur.com/fcdQZtj.png)
6. The most interesting of all this is the **_performance_** if you run a **lighthouse**  or **page speed** test you will reach a **100  score**.
  - ![Reach 100% Score lighthouse with Next.js and Baseweb ui](https://media.giphy.com/media/Cd9XcHdZEIcaA/giphy.gif)

Of course, you will think that is just a menu, and it's different from a real big application but honestly, **I've never reached a 100 score** when using a collection/kit/framework of components as I mentioned (Antd, Bootstrap, etc) before.

Especially when you set it `globally`, 'cause now you can consume ANY component of Baseweb, but it will generate just the critical CSS, and like I mentioned before they're emphasized **performance**

>Of Course, Basewebui has its  _bad things_
### PROS:
* **Highly**: performant
* **Very**: customizable (Almost every aspect of the components) you can use Styletron for this or [Baseui overrides](https://baseweb.design/guides/understanding-overrides)
* [**Themeable**](https://baseweb.design/guides/theming/) This is very useful when you don't want generic styles.
* **Private**: (you can expect quality and maintenance of the project from UBER) but of course you can still contribute.

### CONS:

* **CSS-in-JS**: Some people don't like to use CSS-in-JS, so if this is your case Baseweb is not for you.
* **Confusing**: At the beginning (How Styletron works specifically)
* **Knowledge**: (it would be difficult and confusing if you don't know how to set a good CSS-in-JS architecture)
* **Framework**: it's a framework everything is pre-created.

## Conclusions

There's a lot of **UI Kits**, **CSS Frameworks** out there for every Javascript framework and of course, everyone has their particularities and shines in different ways, of course As you may know this framework (like other frameworks or even technologies)  is not perfect in all situations, you need to check what is better for each situation.

I highly recommended to you if you like to use a **collection or kit of components** pre-made that you can "install" once, use in the whole application, and you need a **great performance** in it. Of course, has pros, cons but like I mentioned before it's great when you want great performance without problems.

Of Course, don't forget that this is a **framework** so is better that you know the basis of CSS and of course Javascript, 'cause knowledge is like a plant if you have solid roots, make fruits it will be really easy.

> Thank you for taking your time to read this. I appreciate any comments/feedback or questions you may have.

> [You can check the final code in GitHub, feel free to fork or clone it](https://github.com/irvv17/Nextjs-Baseweb-Boilerplate)

> [Live preview,  deployed in ▲Vercel](https://nextjs-baseweb-boilerplate-irvv17.vercel.app/) (try a lighthouse test)