Design System Components Using Tailwind

Script Generator

We are going to place these components inside atoms folder.

npx rsb-gen atoms/ComponentName
  • ComponentName.stories.tsx
  • ComponentName.test.tsx
  • index.ts

Utility classes Vs Component abstraction

Why should we create a Button component when we can use the utility classes to create one on the fly?

// Abstracted component
<Button {…props}>Hello world</Button>
// Utility classes on the fly.
<button className="bg-primary-600 px-3 py-2 rounded">Hello world</button>
  • Consistency: If the developer thinks, ‘I need a big button. What paddings should I give?’ the application will end up having thousands of different buttons.
  • Cognitively non-demanding: Using an abstracted button with a predetermined API will reduce the choices the developer needs to make and hence brings down the cognitive overload of the developer.


Run the below command to generate the button component inside the atoms folder.

npx rsb-gen atoms/Button


The below are the props the button component is going to have with children being the mandatory* prop.

  • variant: ‘contained’ | ‘outlined’ | ‘text’
  • color: ‘primary’ | ‘success’ | ‘error’ — Our application does not have a secondary color.
  • size: ‘sm’ | ‘md’ | ‘lg’ — This is the scale we are going with. This scale can evolve to contain xs ,xl and so on if needed.
  • fullWidth: true | false
  • disabled: true | false
  • clickAction: Function — The callback function.
  • classes: string — This is a fire exit where the developer can pass any CSS class name.


  • We create an interface based on the requirements.
  • We create variables for possible prop combinations.
  • The developer has to only pass children and the default values will handle the missing props with the most-probable values.


This component will cover the need for all the header texts that the developers don’t have to use <h> tags at all.

npx rsb-gen atoms/Heading


  • children*: string | ReactElement
  • variant: heading-1’ | ‘heading-2’ | ‘heading-3’
  • weight: ‘normal’ | ‘medium’ | ‘semibold’ | ‘bold’ | ‘extrabold’
  • headerType: ‘h1’ | ‘h2’ | ‘h3’ | ‘h4’ | ‘h5’ | ‘h6’
  • classes: string


  • Header tag: The headerType prop decides the HTML header tag of the component. We can choose headerType: h1 and variant: heading-3 when the page heading is not the prominent thing on the page.
  • Trim later: The weight increases the overall combinations. So, at some point in the development, we can run an analysis tool to find the usage of props and limit them.


Let's create a component for body copy.


  • children: string | ReactElement
  • size: ‘xs’ | ‘sm’ | ‘md’ | ‘lg’
  • muted: true | false
  • textType:p’ | ‘span’
  • uppercase: true | false
  • clamp: ‘none’ | ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘5’ | ‘6’
  • classes: string



  • src*: string
  • size: ‘xs’ | ‘sm’ | ‘md’ | ‘lg’
  • rounded: ‘none’ | ‘xs’ | ‘sm’ | ‘md’ | ‘lg’ | ‘full’
  • ring: true | false
  • shadow: true | false


Skeletons not only provide a smooth loading experience but also improve the cumulative layout shift score as the space for the items is already occupied in the screen.


  • shape: ‘circle’ | ‘rectangle’
  • height: ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘5’ | ‘6’ | ‘7’ | ‘8’ | ‘9’ | ‘10’
  • width: ‘w-4/5’ | ‘w-4/6’ | ‘w-5/6’ | ‘w-1/2’ | ‘w-2/3’ | ‘w-3/4’ | ‘w-full’
  • classes: string


The pattern is almost like how we translate the props into our utility classes. In this example, the prop badgeText is just any string. color gets directly translated into corresponding bg, text, and border colors.


  • badgeText*: string
  • color: ‘primary’ | ‘gray’ | ‘red’ | ‘green’
  • classes: string



  • IconComponent*: ReactComponent
  • count: number
  • linkTo: string
  • ariaLabel: string
  • classes: string



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Karthick Ragavendran

Karthick Ragavendran

Fullstack engineer @ | React, Typescript, Redux, JavaScript, UI, Storybook, CSS, UX, Cypress, CI/CD.