Bun.sh with React, Typescript, TailwindCSS and Storybook

Bun.sh with React, Typescript, TailwindCSS and Storybook

Bringing a faster compilation frontend towards with the new released Bun.

Sep 23, 2023·

5 min read

Featured on Hashnode

After the release version of Bun 1.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.

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

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

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

bun dev

and it should be running in your http://localhost:5173/

Adding TailwindCSS

Since we are using the Vite app, we will follow the installation for Tailwind with Vite. To install the TailwindCSS library, the Bun command is similar to how Yarn or NPM is used.

bun add -d tailwindcss postcss autoprefixer

following the TailwindCSS tutorial we need to init the configuration.

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

/** @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

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

Adding ShadcnUI

ShadcnUI 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 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

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

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

bun add -d @types/node

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

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

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.

✔ 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.

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 for this.

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.

bun storybook

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

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

// .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.