# Bun.sh with React, Typescript, TailwindCSS and Storybook

After the release [version of Bun 1.0](https://bun.sh/blog/bun-v1.0) last few weeks, it has moved the industry benchmark in the javascript world almost as fast as other popular programming languages that are widely known to be fast (like Go and Rust) which is proof that the major focus towards improving performance is still in demand and the potential have not yet reached its limits.

The tutorial will cover installing Bun and creating a React project with Typescript, and Vite and the styling will be using TailwindCSS, ShadcnUI and Storybook.

This tutorial will be using Mac since the stable version of Bun is only for Mac currently, the Windows version is said to be experimental.

### Getting Started

Install Bun with the following command from the Bun website.

```bash
curl -fsSL https://bun.sh/install | bash
```

After installing, we create a react project with the following command

```bash
bun create vite
```

The project name is left default as `vite-project`, and React as the framework with Typescript turned on.

Boom 💥 the installation process did not even more than 10 seconds.

The development server can be started by

```bash
bun dev
```

and it should be running in your [http://localhost:5173/](http://localhost:5173/)

### Adding TailwindCSS

Since we are using the Vite app, we will follow the installation for [Tailwind with Vite](https://tailwindcss.com/docs/guides/vite). To install the TailwindCSS library, the Bun command is similar to how Yarn or NPM is used.

```bash
bun add -d tailwindcss postcss autoprefixer
```

following the TailwindCSS tutorial we need to init the configuration.

```typescript
bunx tailwindcss init -p
// or 
bun run tailwindcss init -p
```

On NPM we have npx, in Bun, we have bunx to help initialize the module right away.

The rest of the steps are supposed the same as the ones from the guide from TailwindCSS documentation.

edit `content` inside `tailwind.config.js`

```typescript
/** @type {import('tailwindcss').Config} */
export default {
  content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

replace the content of your `index.css` with the TailwindCSS directives

```css
/* index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
```

### Adding ShadcnUI

[ShadcnUI](https://ui.shadcn.com/) has been a great help in improving the adoption of best practices in styling the whole React projects in the industry.

We will follow [this guide](https://ui.shadcn.com/docs/installation/vite) from the website documentation.

Since the first two are the same as TailwindCSS documentation, we will skip that and straight towards the *Absolute Path* configuration in Vite.

Add this part of the code inside `compilerOptions` object

```json
"baseUrl": ".",
"paths": {
  "@/*": ["./src/*"]
}
```

Add `@types/node` for type safety for importing from the path module.

```bash
bun add -d @types/node
```

And change the vite.config.ts to understand the @ sign as well as an alias of the "src" folder.

```typescript
import path from 'path'
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
})
```

Now we can run the init command from ShadcnUI

```bash
bunx shadcn-ui@latest init
```

Pick Typescript and Default style then Slate as base color when asked. For the global CSS, src/index.css - and the rest of the questions mostly we will use the default answer for it.

```bash
✔ Would you like to use TypeScript (recommended)? … no / yes
✔ Which style would you like to use? › Default
✔ Which color would you like to use as base color? › Slate
✔ Where is your global CSS file? … src/index.css
✔ Would you like to use CSS variables for colors? … no / yes
✔ Where is your tailwind.config.js located? … tailwind.config.js
✔ Configure the import alias for components: … @/components
✔ Configure the import alias for utils: … @/lib/utils
✔ Are you using React Server Components? … no / yes
✔ Write configuration to components.json. Proceed? … yes
```

After that is set up we can try to add a Button component from the library.

```bash
bunx shadcn-ui@latest add button
```

That's it! initializing ShadcnUI and adding more components - it is advised to explore their documentation as needed.

### Adding Storybook

We will be following the [Storybook documentation](https://storybook.js.org/docs/react/get-started/install) for this.

```bash
bunx storybook@latest init --skip-install
bun i
```

We are skipping the installation since Bun is new hence they are not detected by the Storybook CLI and by default it will use NPM.

After that, we will have `.storybook` folder and `stories` folder added to the root folder.

Run the Storybook and follow their Tour.

```typescript
bun storybook
```

Let's update the Story in the `stories/Button.stories.ts` to use the Button that has been generated by ShadcnUI.

```typescript
import type { Meta, StoryObj } from '@storybook/react'

import { Button } from '@/components/ui/button'

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta = {
  title: 'Example/Button',
  component: Button,
  parameters: {
    // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/react/configure/story-layout
    layout: 'centered',
  },
  // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/react/writing-docs/autodocs
  tags: ['autodocs'],
  // More on argTypes: https://storybook.js.org/docs/react/api/argtypes
  argTypes: {
    // backgroundColor: { control: 'color' },
  },
} satisfies Meta<typeof Button>

export default meta
type Story = StoryObj<typeof meta>

// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const Primary: Story = {
  args: {
    variant: 'default',
    children: 'Primary',
  },
}

export const Secondary: Story = {
  args: {
    variant: 'secondary',
    children: 'Secondary',
  },
}

export const Large: Story = {
  args: {
    size: 'lg',
    children: 'Large',
  },
}

export const Small: Story = {
  args: {
    size: 'sm',
    children: 'Small',
  },
}
```

Update the import and all the props to match our Button props.

However, even after adding all of this, the styling from TailwindCSS has not applying yet. This is because we have not import the index.css into our Storybook. We can do this by adding an import into our `.storybook/preview.ts`

```typescript
// .storybook/preview.ts

import '@/index.css'

...
```

Once, save the hot reload should apply and the styling should be applied to our Butotn stories.

---

### Final Thoughts

Testing Bun with React, Typescript, Vite, TailwindCSS, ShadcnUI and Storybook has been successful so far. The installation and runtime speed of Bun has been a breeze. Looking forward to more development from Bun, Node and Deno in the Javascript world to keep improving the industry standard ahead for years to come.
