Published on

What is NextUI?

Table of Contents

https://nextui.org/

What is NextUI?

A React UI library: NextUI provides a collection of pre-built React components to streamline your website or application development process. Built on Tailwind CSS: It uses the popular Tailwind CSS utility framework for its styling, giving you access to Tailwind's classes for customization. Accessibility and design focus: NextUI prioritizes creating components that follow web accessibility guidelines (WAI-ARIA standards) and offer a clean, modern aesthetic.

NextUI offers over 40+ beautifully designed components that are built with React Aria and Framer Motion for animations. The library is fully typed with TypeScript, providing excellent developer experience with autocomplete and type checking. Each component is carefully crafted to be responsive, accessible, and customizable out of the box.

The library stands out for its modern design system that follows the latest UI trends while maintaining excellent performance. Components are tree-shakeable, meaning you only bundle what you use, keeping your application lightweight. NextUI also provides automatic CSS-in-JS optimization, ensuring minimal runtime overhead.

Why use NextUI?

Speed and efficiency: If you want to create beautiful and functional user interfaces quickly, NextUI allows you to leverage its well-designed components instead of building everything from scratch. Customization: Although built on Tailwind CSS, NextUI offers multiple ways to customize the default look of components including theming and CSS overrides. Accessibility: It helps you build inclusive websites and applications that can be used by people with disabilities. Growing Community: NextUI has a supportive and expanding community, providing resources and assistance for those using the library.

When to consider NextUI

NextUI is a great fit for React projects where:

You need to build websites or apps quickly. You prefer component-based development. UI design isn't your primary expertise, and you want a solid, visually appealing base. Accessibility is a top priority.

Installation and Setup

Getting started with NextUI in your Next.js project is straightforward. Here's a complete step-by-step guide:

Basic Installation

First, install NextUI and its peer dependencies:

npm install @nextui-org/react framer-motion

Setup with Next.js App Router

For Next.js 13+ with the App Router, configure your app/providers.tsx:

'use client'

import {NextUIProvider} from '@nextui-org/react'

export function Providers({children}: { children: React.ReactNode }) {
  return (
    <NextUIProvider>
      {children}
    </NextUIProvider>
  )
}

Then wrap your root layout in app/layout.tsx:

import {Providers} from './providers'

export default function RootLayout({children}: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <Providers>
          {children}
        </Providers>
      </body>
    </html>
  )
}

Tailwind CSS Configuration

NextUI requires Tailwind CSS. Update your tailwind.config.js:

import {nextui} from "@nextui-org/react"

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./node_modules/@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}"
  ],
  theme: {
    extend: {},
  },
  darkMode: "class",
  plugins: [nextui()],
}

Key Components

NextUI provides a comprehensive set of components for building modern web applications. Let's explore the most commonly used ones:

Button Component

Buttons are fundamental to any UI. NextUI offers extensive button variations:

import {Button} from "@nextui-org/react"

export default function ButtonExample() {
  return (
    <div className="flex gap-4">
      <Button color="primary">Primary</Button>
      <Button color="secondary">Secondary</Button>
      <Button color="success">Success</Button>
      <Button color="warning">Warning</Button>
      <Button color="danger">Danger</Button>

      {/* Variants */}
      <Button variant="solid">Solid</Button>
      <Button variant="bordered">Bordered</Button>
      <Button variant="light">Light</Button>
      <Button variant="flat">Flat</Button>
      <Button variant="ghost">Ghost</Button>

      {/* Sizes */}
      <Button size="sm">Small</Button>
      <Button size="md">Medium</Button>
      <Button size="lg">Large</Button>

      {/* Loading state */}
      <Button isLoading>Loading</Button>
    </div>
  )
}

Card Component

Cards are perfect for organizing content:

import {Card, CardHeader, CardBody, CardFooter, Image, Button} from "@nextui-org/react"

export default function CardExample() {
  return (
    <Card className="max-w-[400px]">
      <CardHeader className="flex gap-3">
        <Image
          alt="logo"
          height={40}
          radius="sm"
          src="/logo.png"
          width={40}
        />
        <div className="flex flex-col">
          <p className="text-md">NextUI</p>
          <p className="text-small text-default-500">nextui.org</p>
        </div>
      </CardHeader>
      <CardBody>
        <p>Make beautiful websites regardless of your design experience.</p>
      </CardBody>
      <CardFooter>
        <Button color="primary">Learn More</Button>
      </CardFooter>
    </Card>
  )
}

Modals for dialogs and overlays:

import {Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Button, useDisclosure} from "@nextui-org/react"

export default function ModalExample() {
  const {isOpen, onOpen, onOpenChange} = useDisclosure()

  return (
    <>
      <Button onPress={onOpen}>Open Modal</Button>
      <Modal isOpen={isOpen} onOpenChange={onOpenChange}>
        <ModalContent>
          {(onClose) => (
            <>
              <ModalHeader className="flex flex-col gap-1">
                Modal Title
              </ModalHeader>
              <ModalBody>
                <p>This is the modal content. You can add any components here.</p>
              </ModalBody>
              <ModalFooter>
                <Button color="danger" variant="light" onPress={onClose}>
                  Close
                </Button>
                <Button color="primary" onPress={onClose}>
                  Action
                </Button>
              </ModalFooter>
            </>
          )}
        </ModalContent>
      </Modal>
    </>
  )
}

Input Components

Forms are essential, and NextUI provides beautiful input components:

import {Input, Textarea, Select, SelectItem} from "@nextui-org/react"

export default function InputExample() {
  return (
    <div className="flex flex-col gap-4 w-full max-w-xs">
      <Input
        type="email"
        label="Email"
        placeholder="Enter your email"
      />

      <Input
        type="password"
        label="Password"
        placeholder="Enter your password"
      />

      <Textarea
        label="Description"
        placeholder="Enter your description"
      />

      <Select
        label="Select an option"
        placeholder="Choose one"
      >
        <SelectItem key="option1" value="option1">
          Option 1
        </SelectItem>
        <SelectItem key="option2" value="option2">
          Option 2
        </SelectItem>
      </Select>
    </div>
  )
}

Building navigation is simple with NextUI:

import {Navbar, NavbarBrand, NavbarContent, NavbarItem, Link, Button} from "@nextui-org/react"

export default function NavigationExample() {
  return (
    <Navbar>
      <NavbarBrand>
        <p className="font-bold text-inherit">ACME</p>
      </NavbarBrand>
      <NavbarContent className="hidden sm:flex gap-4" justify="center">
        <NavbarItem>
          <Link color="foreground" href="#">
            Features
          </Link>
        </NavbarItem>
        <NavbarItem isActive>
          <Link href="#" aria-current="page">
            Customers
          </Link>
        </NavbarItem>
        <NavbarItem>
          <Link color="foreground" href="#">
            Integrations
          </Link>
        </NavbarItem>
      </NavbarContent>
      <NavbarContent justify="end">
        <NavbarItem className="hidden lg:flex">
          <Link href="#">Login</Link>
        </NavbarItem>
        <NavbarItem>
          <Button as={Link} color="primary" href="#" variant="flat">
            Sign Up
          </Button>
        </NavbarItem>
      </NavbarContent>
    </Navbar>
  )
}

Theming and Customization

NextUI provides powerful theming capabilities that allow you to customize every aspect of your components to match your brand identity.

Custom Theme Configuration

Extend NextUI's default theme in your tailwind.config.js:

import {nextui} from "@nextui-org/react"

module.exports = {
  plugins: [
    nextui({
      themes: {
        light: {
          colors: {
            primary: {
              DEFAULT: "#0070F3",
              foreground: "#FFFFFF",
            },
            secondary: {
              DEFAULT: "#7928CA",
              foreground: "#FFFFFF",
            },
            success: {
              DEFAULT: "#17C964",
              foreground: "#FFFFFF",
            },
            warning: {
              DEFAULT: "#F5A524",
              foreground: "#FFFFFF",
            },
            danger: {
              DEFAULT: "#F31260",
              foreground: "#FFFFFF",
            },
          },
        },
        dark: {
          colors: {
            primary: {
              DEFAULT: "#0072F5",
              foreground: "#FFFFFF",
            },
            secondary: {
              DEFAULT: "#9750DD",
              foreground: "#FFFFFF",
            },
          },
        },
      },
    }),
  ],
}

Component-Level Customization

You can customize individual components using the classNames prop:

import {Button} from "@nextui-org/react"

export default function CustomButton() {
  return (
    <Button
      classNames={{
        base: "bg-gradient-to-tr from-pink-500 to-yellow-500 border-small",
        content: "drop-shadow shadow-black text-white",
      }}
    >
      Custom Styled Button
    </Button>
  )
}

CSS Variables

NextUI uses CSS variables that you can override:

:root {
  --nextui-primary: 0 112 243;
  --nextui-secondary: 121 40 202;
  --nextui-success: 23 201 100;
}

Dark Mode Implementation

NextUI has built-in dark mode support that integrates seamlessly with Next.js.

Setting Up Dark Mode

Install next-themes for theme management:

npm install next-themes

Update your providers to include theme support:

'use client'

import {NextUIProvider} from '@nextui-org/react'
import {ThemeProvider as NextThemesProvider} from 'next-themes'

export function Providers({children}: { children: React.ReactNode }) {
  return (
    <NextUIProvider>
      <NextThemesProvider attribute="class" defaultTheme="dark">
        {children}
      </NextThemesProvider>
    </NextUIProvider>
  )
}

Theme Switcher Component

Create a component to toggle between themes:

'use client'

import {useTheme} from 'next-themes'
import {Switch} from '@nextui-org/react'
import {useEffect, useState} from 'react'

export default function ThemeSwitcher() {
  const [mounted, setMounted] = useState(false)
  const {theme, setTheme} = useTheme()

  useEffect(() => {
    setMounted(true)
  }, [])

  if (!mounted) return null

  return (
    <Switch
      isSelected={theme === 'dark'}
      onValueChange={(isSelected) => setTheme(isSelected ? 'dark' : 'light')}
    >
      Dark Mode
    </Switch>
  )
}

Form Handling

Building forms with NextUI is intuitive and provides excellent user experience.

Complete Form Example

Here's a comprehensive form with validation:

'use client'

import {useState} from 'react'
import {Input, Button, Card, CardBody} from '@nextui-org/react'

export default function ContactForm() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    message: ''
  })
  const [errors, setErrors] = useState({})

  const validate = () => {
    const newErrors = {}

    if (!formData.name.trim()) {
      newErrors.name = 'Name is required'
    }

    if (!formData.email.trim()) {
      newErrors.email = 'Email is required'
    } else if (!/\S+@\S+\.\S+/.test(formData.email)) {
      newErrors.email = 'Email is invalid'
    }

    if (!formData.message.trim()) {
      newErrors.message = 'Message is required'
    }

    setErrors(newErrors)
    return Object.keys(newErrors).length === 0
  }

  const handleSubmit = (e) => {
    e.preventDefault()

    if (validate()) {
      console.log('Form submitted:', formData)
      // Handle form submission
    }
  }

  return (
    <Card className="max-w-md mx-auto">
      <CardBody>
        <form onSubmit={handleSubmit} className="flex flex-col gap-4">
          <Input
            label="Name"
            placeholder="Enter your name"
            value={formData.name}
            onChange={(e) => setFormData({...formData, name: e.target.value})}
            isInvalid={!!errors.name}
            errorMessage={errors.name}
          />

          <Input
            type="email"
            label="Email"
            placeholder="Enter your email"
            value={formData.email}
            onChange={(e) => setFormData({...formData, email: e.target.value})}
            isInvalid={!!errors.email}
            errorMessage={errors.email}
          />

          <Textarea
            label="Message"
            placeholder="Enter your message"
            value={formData.message}
            onChange={(e) => setFormData({...formData, message: e.target.value})}
            isInvalid={!!errors.message}
            errorMessage={errors.message}
          />

          <Button type="submit" color="primary">
            Submit
          </Button>
        </form>
      </CardBody>
    </Card>
  )
}

NextUI vs Other Libraries

Understanding how NextUI compares to other popular UI libraries helps you make informed decisions.

NextUI vs Material-UI (MUI)

NextUI Advantages:

  • Smaller bundle size with better tree-shaking
  • Built specifically for Tailwind CSS ecosystem
  • More modern, minimalist design out of the box
  • Better TypeScript support
  • Simpler API and less boilerplate

Material-UI Advantages:

  • Larger component library
  • More mature ecosystem with extensive documentation
  • Follows Material Design guidelines strictly
  • More third-party integrations

NextUI vs Chakra UI

NextUI Advantages:

  • Better performance with smaller runtime
  • Tailwind CSS integration for familiar workflow
  • More polished default components
  • Built-in Framer Motion animations

Chakra UI Advantages:

  • More extensive theming system
  • Larger community and ecosystem
  • More accessibility features out of the box
  • Better documentation for complex scenarios

NextUI vs shadcn/ui

NextUI Advantages:

  • Pre-built components ready to use
  • Consistent design system
  • Less setup required
  • Official package management

shadcn/ui Advantages:

  • Full ownership of code (copy-paste approach)
  • More customization flexibility
  • No dependency on external packages
  • Can mix and match with other libraries

Responsive Design

NextUI components are responsive by default, adapting seamlessly to different screen sizes.

Built-in Responsive Props

Many NextUI components support responsive props:

import {Button, Card} from "@nextui-org/react"

export default function ResponsiveExample() {
  return (
    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
      <Card className="p-4">
        <Button
          size={{
            initial: "sm",
            sm: "md",
            md: "lg"
          }}
          className="w-full"
        >
          Responsive Button
        </Button>
      </Card>
    </div>
  )
}

Mobile Navigation Example

import {
  Navbar,
  NavbarBrand,
  NavbarContent,
  NavbarItem,
  NavbarMenuToggle,
  NavbarMenu,
  NavbarMenuItem,
  Link,
  Button
} from "@nextui-org/react"
import {useState} from "react"

export default function ResponsiveNav() {
  const [isMenuOpen, setIsMenuOpen] = useState(false)

  const menuItems = ["Features", "Customers", "Pricing", "Company"]

  return (
    <Navbar onMenuOpenChange={setIsMenuOpen}>
      <NavbarContent>
        <NavbarMenuToggle
          aria-label={isMenuOpen ? "Close menu" : "Open menu"}
          className="sm:hidden"
        />
        <NavbarBrand>
          <p className="font-bold text-inherit">ACME</p>
        </NavbarBrand>
      </NavbarContent>

      <NavbarContent className="hidden sm:flex gap-4" justify="center">
        {menuItems.map((item) => (
          <NavbarItem key={item}>
            <Link color="foreground" href="#">
              {item}
            </Link>
          </NavbarItem>
        ))}
      </NavbarContent>

      <NavbarMenu>
        {menuItems.map((item, index) => (
          <NavbarMenuItem key={`${item}-${index}`}>
            <Link
              className="w-full"
              href="#"
              size="lg"
            >
              {item}
            </Link>
          </NavbarMenuItem>
        ))}
      </NavbarMenu>
    </Navbar>
  )
}

Performance Optimization

NextUI is designed with performance in mind, but there are additional strategies to optimize further.

Tree Shaking

Import only what you need to minimize bundle size:

// Good - tree-shakeable
import {Button} from "@nextui-org/react"

// Avoid - imports everything
import * as NextUI from "@nextui-org/react"

Code Splitting

Use dynamic imports for large components:

import dynamic from 'next/dynamic'

const Modal = dynamic(() =>
  import('@nextui-org/react').then(mod => mod.Modal),
  { ssr: false }
)

Bundle Size Optimization

NextUI's core is approximately 50KB gzipped, significantly smaller than alternatives:

  • NextUI: ~50KB
  • Material-UI: ~90KB
  • Chakra UI: ~70KB

Loading Strategies

Implement skeleton loading for better perceived performance:

import {Skeleton, Card} from "@nextui-org/react"

export default function LoadingSkeleton() {
  return (
    <Card className="w-[300px] space-y-5 p-4">
      <Skeleton className="rounded-lg">
        <div className="h-24 rounded-lg bg-default-300"></div>
      </Skeleton>
      <div className="space-y-3">
        <Skeleton className="w-3/5 rounded-lg">
          <div className="h-3 w-3/5 rounded-lg bg-default-200"></div>
        </Skeleton>
        <Skeleton className="w-4/5 rounded-lg">
          <div className="h-3 w-4/5 rounded-lg bg-default-200"></div>
        </Skeleton>
      </div>
    </Card>
  )
}

Real Project Examples

Let's build practical components you'd use in production applications.

Dashboard Card Component

import {Card, CardBody, CardHeader, Progress} from "@nextui-org/react"

export default function DashboardCard({
  title,
  value,
  change,
  progress
}: {
  title: string
  value: string
  change: number
  progress: number
}) {
  return (
    <Card className="w-full">
      <CardHeader className="flex justify-between">
        <h4 className="text-small font-semibold">{title}</h4>
        <span className={change >= 0 ? "text-success" : "text-danger"}>
          {change >= 0 ? "+" : ""}{change}%
        </span>
      </CardHeader>
      <CardBody>
        <p className="text-3xl font-bold mb-4">{value}</p>
        <Progress
          size="sm"
          value={progress}
          color={progress > 70 ? "success" : progress > 40 ? "warning" : "danger"}
        />
      </CardBody>
    </Card>
  )
}

Landing Page Hero Section

import {Button, Image} from "@nextui-org/react"

export default function HeroSection() {
  return (
    <section className="flex flex-col md:flex-row items-center justify-between gap-8 p-8 max-w-7xl mx-auto">
      <div className="flex-1 space-y-6">
        <h1 className="text-5xl font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
          Build Beautiful Interfaces
        </h1>
        <p className="text-xl text-default-600">
          NextUI provides everything you need to create stunning, accessible web applications with ease.
        </p>
        <div className="flex gap-4">
          <Button color="primary" size="lg">
            Get Started
          </Button>
          <Button variant="bordered" size="lg">
            View Docs
          </Button>
        </div>
      </div>
      <div className="flex-1">
        <Image
          src="/hero-image.png"
          alt="Hero"
          className="w-full"
        />
      </div>
    </section>
  )
}

Data Table Component

import {
  Table,
  TableHeader,
  TableColumn,
  TableBody,
  TableRow,
  TableCell,
  Chip,
  Button
} from "@nextui-org/react"

const users = [
  { id: 1, name: "John Doe", email: "[email protected]", status: "active" },
  { id: 2, name: "Jane Smith", email: "[email protected]", status: "inactive" },
  { id: 3, name: "Bob Johnson", email: "[email protected]", status: "active" },
]

export default function UserTable() {
  return (
    <Table aria-label="Users table">
      <TableHeader>
        <TableColumn>NAME</TableColumn>
        <TableColumn>EMAIL</TableColumn>
        <TableColumn>STATUS</TableColumn>
        <TableColumn>ACTIONS</TableColumn>
      </TableHeader>
      <TableBody>
        {users.map((user) => (
          <TableRow key={user.id}>
            <TableCell>{user.name}</TableCell>
            <TableCell>{user.email}</TableCell>
            <TableCell>
              <Chip
                color={user.status === "active" ? "success" : "default"}
                variant="flat"
              >
                {user.status}
              </Chip>
            </TableCell>
            <TableCell>
              <Button size="sm" variant="light">
                Edit
              </Button>
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  )
}

Integration with Next.js 13/14

NextUI works seamlessly with the latest Next.js features, including the App Router and Server Components.

Server Components

NextUI components are client components by default, but you can optimize by using Server Components for static content:

// app/page.tsx (Server Component)
import {Suspense} from 'react'
import ClientCard from './ClientCard'

export default function Page() {
  return (
    <div>
      <h1>Server Rendered Content</h1>
      <Suspense fallback={<div>Loading...</div>}>
        <ClientCard />
      </Suspense>
    </div>
  )
}

// app/ClientCard.tsx (Client Component)
'use client'

import {Card, CardBody} from '@nextui-org/react'

export default function ClientCard() {
  return (
    <Card>
      <CardBody>
        Interactive content that needs client-side JS
      </CardBody>
    </Card>
  )
}

App Router Compatibility

NextUI fully supports Next.js 13/14 App Router with proper TypeScript types:

// app/dashboard/layout.tsx
import {NextUIProvider} from '@nextui-org/react'

export default function DashboardLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <NextUIProvider>
      <div className="min-h-screen">
        {children}
      </div>
    </NextUIProvider>
  )
}

Server Actions Integration

Combine NextUI forms with Server Actions:

'use client'

import {Input, Button} from '@nextui-org/react'
import {useFormState} from 'react-dom'
import {createUser} from './actions'

export default function UserForm() {
  const [state, formAction] = useFormState(createUser, null)

  return (
    <form action={formAction} className="space-y-4">
      <Input
        name="name"
        label="Name"
        isInvalid={!!state?.errors?.name}
        errorMessage={state?.errors?.name}
      />
      <Input
        name="email"
        label="Email"
        type="email"
        isInvalid={!!state?.errors?.email}
        errorMessage={state?.errors?.email}
      />
      <Button type="submit" color="primary">
        Create User
      </Button>
    </form>
  )
}

Best Practices

Follow these guidelines to get the most out of NextUI in your projects.

Accessibility

NextUI components are built with accessibility in mind, but you should still follow best practices:

import {Button, Input, Modal} from "@nextui-org/react"

// Always provide meaningful labels
<Input
  label="Email Address"
  aria-label="Enter your email address"
  aria-describedby="email-helper"
/>

// Use semantic HTML
<Button
  as="a"
  href="/contact"
  aria-label="Navigate to contact page"
>
  Contact Us
</Button>

// Provide ARIA attributes for modals
<Modal
  aria-labelledby="modal-title"
  aria-describedby="modal-description"
>
  <ModalHeader id="modal-title">Title</ModalHeader>
  <ModalBody id="modal-description">Content</ModalBody>
</Modal>

Component Composition

Build reusable, composable components:

import {Card, CardBody, Button} from "@nextui-org/react"

// Create wrapper components for consistency
export function ActionCard({
  title,
  description,
  action,
  onAction
}: {
  title: string
  description: string
  action: string
  onAction: () => void
}) {
  return (
    <Card>
      <CardBody className="space-y-4">
        <h3 className="text-xl font-semibold">{title}</h3>
        <p className="text-default-500">{description}</p>
        <Button color="primary" onPress={onAction}>
          {action}
        </Button>
      </CardBody>
    </Card>
  )
}

Performance Tips

  1. Use lazy loading for heavy components
  2. Implement proper memoization
  3. Avoid unnecessary re-renders
  4. Use the isDisabled prop instead of conditional rendering
import {memo} from 'react'
import {Card} from "@nextui-org/react"

// Memoize components that don't change frequently
const MemoizedCard = memo(function ProductCard({product}) {
  return (
    <Card>
      <CardBody>{product.name}</CardBody>
    </Card>
  )
})

Common Patterns

Here are patterns you'll use repeatedly in NextUI projects.

Layout Pattern

import {Navbar, Link} from "@nextui-org/react"

export default function Layout({children}: {children: React.ReactNode}) {
  return (
    <div className="min-h-screen flex flex-col">
      <Navbar>
        <Link href="/">Home</Link>
        <Link href="/about">About</Link>
      </Navbar>
      <main className="flex-grow container mx-auto p-4">
        {children}
      </main>
      <footer className="bg-default-100 p-4 text-center">
        Footer content
      </footer>
    </div>
  )
}

Form Pattern with React Hook Form

'use client'

import {useForm} from 'react-hook-form'
import {Input, Button} from '@nextui-org/react'

export default function RegistrationForm() {
  const {
    register,
    handleSubmit,
    formState: {errors, isSubmitting}
  } = useForm()

  const onSubmit = async (data) => {
    await new Promise(resolve => setTimeout(resolve, 1000))
    console.log(data)
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
      <Input
        {...register('username', {required: 'Username is required'})}
        label="Username"
        isInvalid={!!errors.username}
        errorMessage={errors.username?.message}
      />
      <Input
        {...register('email', {
          required: 'Email is required',
          pattern: {
            value: /\S+@\S+\.\S+/,
            message: 'Invalid email'
          }
        })}
        type="email"
        label="Email"
        isInvalid={!!errors.email}
        errorMessage={errors.email?.message}
      />
      <Button
        type="submit"
        color="primary"
        isLoading={isSubmitting}
      >
        Register
      </Button>
    </form>
  )
}

List Pattern with Virtualization

For large lists, combine NextUI with virtualization:

import {Card, CardBody} from "@nextui-org/react"
import {useVirtualizer} from '@tanstack/react-virtual'
import {useRef} from 'react'

export default function VirtualizedList({items}: {items: any[]}) {
  const parentRef = useRef(null)

  const rowVirtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 100,
  })

  return (
    <div ref={parentRef} className="h-[600px] overflow-auto">
      <div
        style={{
          height: `${rowVirtualizer.getTotalSize()}px`,
          position: 'relative',
        }}
      >
        {rowVirtualizer.getVirtualItems().map((virtualItem) => (
          <Card
            key={virtualItem.key}
            style={{
              position: 'absolute',
              top: 0,
              left: 0,
              width: '100%',
              transform: `translateY(${virtualItem.start}px)`,
            }}
          >
            <CardBody>
              {items[virtualItem.index].name}
            </CardBody>
          </Card>
        ))}
      </div>
    </div>
  )
}

Related Articles

What is Next.js?

Next.js is a full-stack framework built on top of React (a popular JavaScript UI library). It provides additional structure, features, and optimizations that enhance the core React experience, especially for creating web applications.