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.
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.
$ npx @istmx/ui add bento-gridCopies the install command for your selected package manager.
Dependencies
Usage
Import the component from the file you copied it to, then use it like any other React component.
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
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 arrowAPI reference
items?BentoCardProps[]Optional array of card configuration objects.
children?ReactNodeComposable BentoCard elements or custom content.
cols?numberDesktop grid column count (default: 4).
gap?stringTailwind gap class between cards (default: "gap-3").
gradient?booleanToggle the repeating linear gradient texture (default: true).
gradientAngle?numberAngle of repeating gradient lines in degrees (default: 315).
gradientOpacity?numberOpacity of the repeating gradient texture (default: 0.01).
gradientSpacing?numberSpacing between repeating gradient lines in pixels (default: 24).
gradientColor?stringColor of repeating gradient lines (default: "var(--foreground)").
titleReactNodeCard title or headline.
description?ReactNodeCard secondary supporting text.
icon?ReactNodeIcon element rendered in the micro-interaction badge.
badge?ReactNodeOptional pill status badge rendered in top-right corner.
href?stringInternal route or external URL. Renders Next.js Link when provided.
external?booleanForce external link behavior with target="_blank" and noopener.
cta?ReactNodeAction link text with animated arrow indicator.
ctaHref?stringOptional separate href targeting only the CTA element.
header?ReactNodeSlot for media, image previews, canvas, or custom headers.
footer?ReactNodeSlot for metadata, extra actions, or tags.
featured?booleanWhether 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
