Bento Grid

An adaptive, high-impact grid system designed for feature showcases. Utilizes CSS Grid spanning logic to create a balanced visual hierarchy for modern SaaS and landing pages.

Live Preview

Built for the Modern Stack

Everything you need to ship production-ready interfaces in record time.

Server-Side Performance

Optimized for Next.js 15 App Router. Zero hydration mismatch and blazing fast LCP scores.

export function ForkButton() {
return <button className="bg-emerald-600 text-white">
Fork Me
</button>
}

Enterprise Security

Strict CSP compliance and sanitized inputs by default.

Responsive

Mobile-first approach to every component.

Global Edge

Deploy to any edge network instantly.

Customized Themes

Powerful CSS variables and Tailwind integration. Switch from Emerald to Rose in a single line.

Open Source

MIT Licensed. Fork it, change it, own it.

Dependencies

npm installframer-motionlucide-react

Utils

import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

Code

"use client";
import React from "react";
import { motion } from "framer-motion";
import { Zap, Shield, Smartphone, Globe, Code, Cpu } from "lucide-react";
import { cn } from "@/lib/utils";

interface BentoItemProps {
  title: string;
  description: string;
  icon: React.ReactNode;
  className?: string;
  graphic?: React.ReactNode;
}

const BentoCard = ({
  title,
  description,
  icon,
  className,
  graphic,
}: BentoItemProps) => (
  <motion.div
    whileHover={{ y: -5 }}
    initial={{ opacity: 0, y: 20 }}
    whileInView={{ opacity: 1, y: 0 }}
    viewport={{ once: true }}
    className={cn(
      "group relative overflow-hidden rounded-3xl border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900/50 p-6 flex flex-col justify-between transition-all hover:shadow-2xl hover:shadow-emerald-500/10",
      className,
    )}
  >
    <div className="absolute -right-10 -top-10 h-32 w-32 rounded-full bg-emerald-500/5 blur-3xl group-hover:bg-emerald-500/10 transition-colors" />

    <div>
      <div className="mb-4 inline-flex h-12 w-12 items-center justify-center rounded-xl bg-gray-500/10 text-gray-600 dark:text-gray-400">
        {icon}
      </div>
      <h3 className="text-xl font-bold tracking-tight dark:text-white">
        {title}
      </h3>
      <p className="mt-2 text-sm text-zinc-600 dark:text-zinc-400 leading-relaxed">
        {description}
      </p>
    </div>

    {graphic && (
      <div className="mt-6 w-full flex justify-center">{graphic}</div>
    )}
  </motion.div>
);

export default function BentoGrid() {
  return (
    <section className="py-24 px-6 max-w-7xl mx-auto">
      <div className="mb-12 text-center">
        <h2 className="text-4xl md:text-5xl font-black tracking-tighter dark:text-white">
          Built for the <span className="text-[#7A7A73]">Modern Stack</span>
        </h2>
        <p className="text-zinc-500 mt-4 max-w-lg mx-auto">
          Everything you need to ship production-ready interfaces in record
          time.
        </p>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-4 md:grid-rows-3 gap-4 h-full md:h-[800px]">
        <BentoCard
          title="Server-Side Performance"
          description="Optimized for Next.js 15 App Router. Zero hydration mismatch and blazing fast LCP scores."
          icon={<Zap size={24} />}
          className="md:col-span-2 md:row-span-2 bg-gray-50/50 dark:bg-gray-950/10 border-gray-500/20"
          graphic={<CodeGraphic />}
        />

        <BentoCard
          title="Enterprise Security"
          description="Strict CSP compliance and sanitized inputs by default."
          icon={<Shield size={24} />}
          className="md:col-span-1 md:row-span-2"
        />

        <BentoCard
          title="Responsive"
          description="Mobile-first approach to every component."
          icon={<Smartphone size={24} />}
          className="md:col-span-1 md:row-span-1"
        />

        <BentoCard
          title="Global Edge"
          description="Deploy to any edge network instantly."
          icon={<Globe size={24} />}
          className="md:col-span-1 md:row-span-1"
        />

        <BentoCard
          title="Customized Themes"
          description="Powerful CSS variables and Tailwind integration. Switch from Emerald to Rose in a single line."
          icon={<Cpu size={24} />}
          className="md:col-span-3 md:row-span-1 flex-row items-center gap-6"
          graphic={<ThemeToggleGraphic />}
        />

        <BentoCard
          title="Open Source"
          description="MIT Licensed. Fork it, change it, own it."
          icon={<Code size={24} />}
          className="md:col-span-1 md:row-span-1"
        />
      </div>
    </section>
  );
}

function CodeGraphic() {
  return (
    <div className="w-full h-32 bg-zinc-950 rounded-xl p-4 font-mono text-[10px] text-emerald-400/80 border border-emerald-500/20 overflow-hidden">
      <div className="flex gap-2 mb-2">
        <div className="w-2 h-2 rounded-full bg-red-500/50" />
        <div className="w-2 h-2 rounded-full bg-yellow-500/50" />
        <div className="w-2 h-2 rounded-full bg-green-500/50" />
      </div>
      {/* replace your code here */}
      <code>
        {`export function ForkButton() {`} <br />
        {`  return <button className="bg-emerald-600 text-white">`} <br />
        {`    Fork Me`} <br />
        {`  </button>`} <br />
        {`}`}
      </code>
    </div>
  );
}

function ThemeToggleGraphic() {
  return (
    <div className="flex gap-2">
      {[1, 2, 3].map((i) => (
        <div
          key={i}
          className={cn(
            "w-8 h-8 rounded-full border-2",
            i === 1
              ? "bg-emerald-500 border-white"
              : i === 2
                ? "bg-rose-500 border-transparent"
                : "bg-violet-500 border-transparent",
          )}
        />
      ))}
    </div>
  );
}

Props

PropTypeDefaultDescription
titlestring-The primary heading of the card.
descriptionstring-Supporting text for the feature.
iconReactNode-Lucide icon or custom SVG.
classNamestringundefinedTailwind classes for grid spanning.
graphicReactNodenullOptional visual element (code/charts).