Docs
Next.js

Next.js

Installation guide for DuckUI Component Library.

Create project

Start by creating a new Next.js project using create-next-app:

npx create-next-app@latest my-app --typescript --tailwind --eslint

Run the CLI

Run the shadcn-ui init command to setup your project:

npx duck-ui@latest init

Configure components.json

You will be asked a few questions to configure components.json:

Which style would you like to use? › Default
Which color would you like to use as base color? › Slate
Do you want to use CSS variables for colors? › no / yes

Fonts

I use Inter as the default font. Inter is not required. You can replace it with any other font.

Here's how I configure Inter for Next.js:

1. Import the font in the root layout:

import "@/styles/globals.css"
import { Inter as FontSans } from "next/font/google"
 
import { cn } from "@/lib/utils"
 
const fontSans = FontSans({
  subsets: ["latin"],
  variable: "--font-sans",
})
 
export default function RootLayout({ children }: RootLayoutProps) {
  return (
    <html lang="en" suppressHydrationWarning>
      <head />
      <body
        className={cn(
          "min-h-screen bg-background font-sans antialiased",
          fontSans.variable
        )}
      >
        ...
      </body>
    </html>
  )
}

2. Configure theme.extend.fontFamily in tailwind.config.js

const { fontFamily } = require('tailwindcss/defaultTheme')
 
/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: ['class'],
  content: ['app/**/*.{ts,tsx}', 'components/**/*.{ts,tsx}'],
  theme: {
    extend: {
      fontFamily: {
        sans: ['var(--font-sans)', ...fontFamily.sans],
      },
    },
  },
}

App structure

Here's how I structure my Next.js apps. You can use this as a reference:

.
├── app
│   ├── layout.tsx
│   └── page.tsx
├── components
│   ├── layouts
│   │   ├── Header
│   │   │   ├── Header.tsx
│   │   │   └── index.ts
│   │   └── index.ts
│   ├── Ui
│   │   ├── Button
│   │   │   ├── Header.tsx
│   │   │   └── index.ts
│   │   ├── index.ts
│   │   └── ...
│   ├── Pages
│   │   ├── Home
│   │   │   ├── Home.tsx
│   │   │   └── index.ts
│   │   ├── index.ts
│   │   └── ...
│   └── ...
├── utils
│   └── cn
│   │   ├── cn.tsx
│   │   └── index.ts
│   └── index.tsx
├── styles
│   └── globals.css
├── next.config.js
├── package.json
├── duck-ui.json
├── postcss.config.js
├── tailwind.config.ts
└── tsconfig.json
  • I place the UI components in the components/Ui folder, where each component has its own subfolder containing the main component file and an index.ts for easier imports.
  • The layouts folder under components contains layout-related components such as <Header />, each organized in its own subfolder.
  • The Pages folder under components is where I organize page-specific components, with each page having its own subfolder.
  • The utils folder contains utility functions, including the cn helper function located in the cn subfolder.
  • The styles folder contains the global CSS, ensuring consistent styling across the application.

That's it

You can now start adding components to your project.

npx duck-ui@latest add button

The command above will add the Button component to your project. You can then import it like this:

import { Button } from '@/components/ui'
import { Inbox } from 'lucide-react'
 
export default function Home() {
  return (
    <div>
        <Button>Button<Button/>
    </div>
  )
}