ant-design css next js npm packages react js shadcn-ui

Set-up Shadcn UI in Next JS

There are 100s of UI Libraries like Material UI, Chakra UI, Bootstrap, etc. while using these libraries we have to Install whole library and only then we can use components and themes they provide. Shadcn UI is an UI library which uses different approach than this, Shadcn UI is based on Tailwind CSS and Radix UI, its most loved and trending among the developer community with over 50K stars on GItHub.

In Shadcn we dont install the whole library all at once instead we copy the source code for the component we need, this helps to keep our project as light as possible also as we are copying the actual source code of the components we can also modify them as we like.

PROs and CONs of using Shadcn UI

PROs

  1. Minimilistic : Each component is very minimislitic and higly customizable.
  2. Accessibility : Shadcn components are fully accessible and follows Web Content Accessibility Guidelines (WCAG) standards.
  3. Easy to Use : We just need to add the component we need and we are ready to use it anywhere in our project.

CONs

Only con that you may find is that as we are adding components everytime it may feel tedious.

Getting started with Shadcn UI

Now lets see how we can integrate Shadcn UI in our Next Js app and use its components

Step 1 : Creating new Next JS app

FIrst of all we need a Next Js app to setup Shadcn UI, you can create a new nextjs app using- following command

npx create-next-app@latest my-app

You can change my-app to whatever name you want to keep for your app.

Press Enter and follow the prompt and configure your app, make sure to choose Tailwind CSS as Shadcn UI depends upon it.

after few seconds a success messege will be shown that means your application has been created successfully.

Navigate to your project directory using cd /my-app

Now run npm run dev to run your application in development mode.

image not found

Step 2 : Initialize dependencies for Shadcn UI

Open new terminal in your project and run npx shadcn-ui@latest init to initialize all Shadcn UI components in your project.

Some prompts will be shown to setup components.json just keep pressing Enter to select default ones.

Step 3 : Configure Fonts ( Optional )

Shadcn UI by default uses Inter font from google but you can change it to whatever you like, to do that you need to edit code inside root Layout.tsx

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={inter.className}>{children}</body>
    </html>
  );
}

Also import cn funtion from utils and use it to wrap tailwind classes which you’ll write on your components because cn funtion is helper funtion for Tailwind Merge and below is the code of utils.ts

import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

Use it like below code in root layout.tsx

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { cn } from "@/lib/utils";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};
export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={cn("min-h-screen mx-auto", inter.className)}>{children}</body>
    </html>
  );
}

4. Adding and using Components from Shadcn

As I already told you unlike other UI libraries we can independently add each components from Shadcn UI in our project.

For example: Lets add a button from Shadcn in our Home page ie. page.tsx

Run following command to add button component in our project

image not found

npx shadcn-ui@latest add button

In page.tsx remove default code and write following code to use <Button> component from button

import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
export default function Home() {
  return (
    <div className={cn("text-center mx-auto ")}>
      <h1>Home Page</h1>
      <Button >Button</Button>
    </div>
  )
}

Output

In your project you can see a folder called components created by Shadcn insde which you can see a subfolder called ui which is going to hold source code for the components we add in our projet from Shadcn UI, and we can even modify the source code to change look and behaviour of the component.

For example lets see the source code for <Button> components

import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
  "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground hover:bg-primary/90",
        destructive:
          "bg-destructive text-destructive-foreground hover:bg-destructive/90",
        outline:
          "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
        secondary:
          "bg-secondary text-secondary-foreground hover:bg-secondary/80",
        ghost: "hover:bg-accent hover:text-accent-foreground",
        link: "text-primary underline-offset-4 hover:underline",
      },
      size: {
        default: "h-10 px-4 py-2",
        sm: "h-9 rounded-md px-3",
        lg: "h-11 rounded-md px-8",
        icon: "h-10 w-10",
      },
    },
    defaultVariants: {
      variant: "default",
      size: "default",
    },
  }
)
export interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {
  asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, size, asChild = false, ...props }, ref) => {
    const Comp = asChild ? Slot : "button"
    return (
      <Comp
        className={cn(buttonVariants({ variant, size, className }))}
        ref={ref}
        {...props}
      />
    )
  }
)
Button.displayName = "Button"
export { Button, buttonVariants }

As you can see in source code we can use varients of the <Button> component

We have 6 varients of <Button>

  1. Default
  2. Destructive
  3. Outline
  4. Secondary
  5. Ghost
  6. Link

To use varient just pass varient prop with any of 6 values

Example: Destructive

import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
export default function Home() {
  return (
    <div className={cn("text-center mx-auto ")}>
      <h1>Home Page</h1>
      <Button variant="destructive" >Button</Button>
    </div>
  )
}

Additional Features

Theme Editor

While cofiguring Shadcn you might have noticed that we choose from two themes Default and New York configuration for the theme exits in global.css in your project

@tailwind base;
@tailwind components;
@tailwind utilities;
 
@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 0 0% 3.9%;
    --card: 0 0% 100%;
    --card-foreground: 0 0% 3.9%;
 
    --popover: 0 0% 100%;
    --popover-foreground: 0 0% 3.9%;
 
    --primary: 0 0% 9%;
    --primary-foreground: 0 0% 98%;
 
    --secondary: 0 0% 96.1%;
    --secondary-foreground: 0 0% 9%;
 
    --muted: 0 0% 96.1%;
    --muted-foreground: 0 0% 45.1%;
 
    --accent: 0 0% 96.1%;
    --accent-foreground: 0 0% 9%;
 
    --destructive: 0 84.2% 60.2%;
    --destructive-foreground: 0 0% 98%;
    --border: 0 0% 89.8%;
    --input: 0 0% 89.8%;
    --ring: 0 0% 3.9%;
 
    --radius: 0.5rem;
  }
 
  .dark {
    --background: 0 0% 3.9%;
    --foreground: 0 0% 98%;
 
    --card: 0 0% 3.9%;
    --card-foreground: 0 0% 98%;
 
    --popover: 0 0% 3.9%;
    --popover-foreground: 0 0% 98%;
 
    --primary: 0 0% 98%;
    --primary-foreground: 0 0% 9%;
 
    --secondary: 0 0% 14.9%;
    --secondary-foreground: 0 0% 98%;
 
    --muted: 0 0% 14.9%;
    --muted-foreground: 0 0% 63.9%;
 
    --accent: 0 0% 14.9%;
    --accent-foreground: 0 0% 98%;
 
    --destructive: 0 62.8% 30.6%;
    --destructive-foreground: 0 0% 98%;
 
    --border: 0 0% 14.9%;
    --input: 0 0% 14.9%;
    --ring: 0 0% 83.1%;
  }
}
 
@layer base {
  * {
    @apply border-border;
  }
  body {
    @apply bg-background text-foreground;
  }
}

As you can see we have configuration for both light and dark mode

Although we can manually customize the theme a better way Shadcn UI provides is Theme Editor where we can visually configure our theme

Customize theme and copy code by clicking on copy code, and replace the theme code in global.css

Conclusion

We just saw basic usage of Shadcn UI but we can do lot more than just adding a button eg. we can add custom themes, we can create complex layouts like dashboard and all.

To learn more and see all available component visit official documentation here.

Thanks for reading till here, Stay healthy Keep coding 🙂

Related Posts

How To Install and Use Flowbite in Next js

Flowbite is an open-source library of UI components based on the utility-first Tailwind CSS framework featuring dark mode support, a Figma design system, templates, and more. It provides…

Using Notistack in Nextjs | React js

Showing toast messages in react apps is a common feature to add, as it’s one of the quickest ways to give feedback to users. There are many toast…

Using React Feather Icons in Next js

Feather Icons is a collection of sleek and beautiful icons that you can use in your projects in different ways and integrate seamlessly with React-based applications. To use…

find unused npm packages

Find and Remove Unused NPM Packages from Your Project

While building apps in an NPM environment it’s easy to accumulate lots of NPM packages in our app that we don’t even need, these package slows down our…

Using Bootstrap Icons in Next js | React

Bootstrap Icons is a Free, high-quality, open-source icon library with over 2,000 icons. You can use them as you like SVGs, SVG sprite, or web fonts. We can…

lucide icons

Using Lucide React Icons in Nextjs | React js

Lucide offers a sleek and versatile icon library that seamlessly integrates with your Next.js or React applications. Let’s explore how to leverage Lucide for beautiful, customizable icons: Lucide…

Leave a Reply

Your email address will not be published. Required fields are marked *