my/ui

Command Palette

Search for a command to run...

All components

Bento Grid

cards

Aceternity UI component.

responsive · 660px

Install

Same command in any shadcn project — React (Vite/CRA), Next.js, Remix, Astro, and more:

$npx shadcn@latest add https://your-domain/r/bento-grid.json

Usage

"use client";

import { BentoGrid, BentoGridItem } from "@/registry/aceternity-ui/bento-grid";

const items = [
  {
    title: "Ship at the speed of thought",
    description:
      "Stop wrestling with boilerplate and focus on what actually matters.",
    header: (
      <div className="flex h-full min-h-[6rem] w-full rounded-lg bg-gradient-to-br from-neutral-100 to-neutral-200 dark:from-neutral-800 dark:to-neutral-900" />
    ),
    className: "md:col-span-2",
  },
  {
    title: "Type-safe by default",
    description: "Full TypeScript inference from props to styles.",
    header: (
      <div className="flex h-full min-h-[6rem] w-full rounded-lg bg-gradient-to-br from-neutral-100 to-neutral-200 dark:from-neutral-800 dark:to-neutral-900" />
    ),
    className: "md:col-span-1",
  },
  {
    title: "Composable primitives",
    description: "Mix and match cells to build any dashboard layout.",
    header: (
      <div className="flex h-full min-h-[6rem] w-full rounded-lg bg-gradient-to-br from-neutral-100 to-neutral-200 dark:from-neutral-800 dark:to-neutral-900" />
    ),
    className: "md:col-span-1",
  },
  {
    title: "Dark mode included",
    description: "Tokens adapt automatically — no extra selectors needed.",
    header: (
      <div className="flex h-full min-h-[6rem] w-full rounded-lg bg-gradient-to-br from-neutral-100 to-neutral-200 dark:from-neutral-800 dark:to-neutral-900" />
    ),
    className: "md:col-span-2",
  },
];

export default function Demo() {
  return (
    <div className="w-full max-w-4xl mx-auto p-6">
      <BentoGrid>
        {items.map((item, i) => (
          <BentoGridItem
            key={i}
            title={item.title}
            description={item.description}
            header={item.header}
            className={item.className}
          />
        ))}
      </BentoGrid>
    </div>
  );
}

Component source

import { cn } from "@/lib/utils";

export const BentoGrid = ({
  className,
  children,
}: {
  className?: string;
  children?: React.ReactNode;
}) => {
  return (
    <div
      className={cn(
        "mx-auto grid max-w-7xl grid-cols-1 gap-4 md:auto-rows-[18rem] md:grid-cols-3",
        className,
      )}
    >
      {children}
    </div>
  );
};

export const BentoGridItem = ({
  className,
  title,
  description,
  header,
  icon,
}: {
  className?: string;
  title?: string | React.ReactNode;
  description?: string | React.ReactNode;
  header?: React.ReactNode;
  icon?: React.ReactNode;
}) => {
  return (
    <div
      className={cn(
        "group/bento shadow-input row-span-1 flex flex-col justify-between space-y-4 rounded-xl border border-neutral-200 bg-white p-4 transition duration-200 hover:shadow-xl dark:border-white/[0.2] dark:bg-black dark:shadow-none",
        className,
      )}
    >
      {header}
      <div className="transition duration-200 group-hover/bento:translate-x-2">
        {icon}
        <div className="mt-2 mb-2 font-sans font-bold text-neutral-600 dark:text-neutral-200">
          {title}
        </div>
        <div className="font-sans text-xs font-normal text-neutral-600 dark:text-neutral-300">
          {description}
        </div>
      </div>
    </div>
  );
};

Dependencies

@tabler/icons-react

Source: Aceternity UI