Layout / COMPONENT

Bento Grid

A flexible, open-source 2-1-2 bento grid with concentric double borders, 315° repeating gradient texture, customizable media slots, and Next.js link navigation.

Live preview

How it works

Hovering any card triggers subtle border brightening, surface lift, and micro-interactions on the card icon and call-to-action arrow. Cards support internal route navigation via Next.js Link, external URLs with target="_blank", or custom click handlers.

Accessibility

Uses semantic headings and article structures, fully accessible Next.js Link or button navigation, visible keyboard focus indicators, and reduced-motion-aware animations.

Limitations

Optimized for responsive 1-column mobile layouts and 4-column desktop grids. For fluid masonry layouts with variable-height infinite scrolling, use a dedicated masonry grid.

Features

  • Fully responsive: 1 column on mobile, 2 columns with centered hero banner on tablet, and 4-column 2-1-2 bento on desktop.
  • Concentric double border with exact 4px gap and responsive hover states.
  • Configurable 315° repeating linear gradient background at both grid and card levels.
  • Supports both data-driven props (items={...}) and composable JSX children (<BentoCard />).
  • Seamless internal Next.js Link page navigation and automatic external URL handling.
  • Rich content slots for icons, badges, media headers, footers, and call-to-action links.
  • Respects prefers-reduced-motion preferences automatically.

Installation

Choose the CLI command or install the component manually.

Package manager
$ npx @istmx/ui add bento-grid

Copies the install command for your selected package manager.

Dependencies

ReactNext.jsMotionTailwind CSS@tabler/icons-reactclsxtailwind-merge

Usage

Import the component from the file you copied it to, then use it like any other React component.

Usage
import { BentoGrid, BentoCard } from '@/components/ui/bento-grid'
import { IconPalette, IconWand, IconCube, IconAccessible, IconGauge } from '@tabler/icons-react'
 
export default function BentoShowcase() {
return (
<BentoGrid
items={[
{
title: 'Craft at every scale',
description:
'Spacing, typography rhythm, and contrast compound into interfaces people feel.',
icon: <IconPalette size={18} stroke={1.5} />,
cta: 'Explore design tokens',
href: '/library',
},
{
title: 'Motion with meaning',
description:
'Every easing curve and spring tension is tuned so micro-interactions feel physical.',
icon: <IconWand size={18} stroke={1.5} />,
cta: 'View physics presets',
href: '/library/animated-text',
},
{
title: 'The architecture beneath',
description:
'An ecosystem of composable tokens, strict types, and structural rules designed to scale.',
icon: <IconCube size={18} stroke={1.5} />,
cta: 'Inspect system',
href: '/library',
},
{
title: 'Accessible by default',
description:
'Visible focus indicators, full keyboard navigation, and reduced-motion preferences.',
icon: <IconAccessible size={18} stroke={1.5} />,
cta: 'Check specs',
href: '/library',
},
{
title: 'Built to perform',
description:
'Lean DOM footprints and minimal re-renders keep modern apps lightning fast.',
icon: <IconGauge size={18} stroke={1.5} />,
cta: 'View on GitHub',
href: 'https://github.com/istmX/istmx-library',
},
]}
/>
)
}

Composition

Composition
BentoGrid
├── Repeating gradient background
└── BentoCard (concentric double border)
├── Icon badge with micro-interaction
├── Title & description
├── Header slot (media / preview / image)
├── Footer / Children slot
└── Action CTA with animated arrow

API reference

items?BentoCardProps[]

Optional array of card configuration objects.

children?ReactNode

Composable BentoCard elements or custom content.

cols?number

Desktop grid column count (default: 4).

gap?string

Tailwind gap class between cards (default: "gap-3").

gradient?boolean

Toggle the repeating linear gradient texture (default: true).

gradientAngle?number

Angle of repeating gradient lines in degrees (default: 315).

gradientOpacity?number

Opacity of the repeating gradient texture (default: 0.01).

gradientSpacing?number

Spacing between repeating gradient lines in pixels (default: 24).

gradientColor?string

Color of repeating gradient lines (default: "var(--foreground)").

titleReactNode

Card title or headline.

description?ReactNode

Card secondary supporting text.

icon?ReactNode

Icon element rendered in the micro-interaction badge.

badge?ReactNode

Optional pill status badge rendered in top-right corner.

href?string

Internal route or external URL. Renders Next.js Link when provided.

external?boolean

Force external link behavior with target="_blank" and noopener.

cta?ReactNode

Action link text with animated arrow indicator.

ctaHref?string

Optional separate href targeting only the CTA element.

header?ReactNode

Slot for media, image previews, canvas, or custom headers.

footer?ReactNode

Slot for metadata, extra actions, or tags.

featured?boolean

Whether the card is the center featured item (defaults to card index 2).

The listed props match the current component implementation.

Data attributes

Bento Grid does not expose custom data attributes.

Examples

BentoGrid organizes features into a balanced 2-1-2 grid layout. The center card is prominently featured with 2x2 spans, while the surrounding cards provide concise, actionable focal points. Pass href to navigate seamlessly with Next.js Link, or use header to embed rich media previews.

Credits & inspiration

Created by Aryan (istmX) for ISTMX. The source-first, copy-and-own philosophy is inspired by shadcn/ui. About the creator