Guide

Getting Started

Install Masonix and render a responsive masonry layout with real cards.

Masonix 1.0 gives you three stable React components for masonry layouts: a lightweight CSS-first grid, a measured balanced layout, and a virtualized feed for large lists. Start with the smallest component that fits the job, then move up only when the layout needs measurement or virtualization.

Install

npm install masonix

Masonix supports React 18 and React 19. It ships layout behavior only; your app owns card markup, imagery, styling, and data loading.

First layout

TaskGrid.tsx
import { clsx } from 'clsx';
import { Masonry } from 'masonix';

type Task = {
  id: string;
  title: string;
  detail: string;
  area: string;
  status: string;
};

function TaskCard({ task }: { task: Task }) {
  return (
    <article
      className={clsx(
        'min-w-0',
        'p-5',
        'rounded-lg border',
        'border-zinc-200/80 bg-white text-zinc-950 dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-50',
      )}
    >
      <div
        className={clsx(
          'flex items-center justify-between gap-3',
          'pb-4',
          'border-b',
          'border-zinc-200/70 dark:border-zinc-800',
        )}
      >
        <span
          className={clsx(
            'font-mono text-[11px] font-medium uppercase tracking-[0.14em]',
            'text-zinc-500 dark:text-zinc-400',
          )}
        >
          {task.area}
        </span>
        <span
          className={clsx(
            'flex items-center gap-1.5',
            'text-xs',
            'text-zinc-500 dark:text-zinc-400',
          )}
        >
          <span
            aria-hidden="true"
            className={clsx(
              'size-1.5 shrink-0',
              'rounded-full',
              'bg-zinc-400 dark:bg-zinc-600',
            )}
          />
          {task.status}
        </span>
      </div>
      <div className="pt-4">
        <h3 className="text-base font-semibold leading-6">{task.title}</h3>
        <p
          className={clsx(
            'mt-2',
            'text-sm leading-6',
            'text-zinc-600 dark:text-zinc-400',
          )}
        >
          {task.detail}
        </p>
      </div>
    </article>
  );
}

export function TaskGrid({ tasks }: { tasks: Task[] }) {
  return (
    <Masonry
      items={tasks}
      columnWidth={190}
      maxColumns={3}
      gap={14}
      itemKey={(task) => task.id}
      render={({ data }) => <TaskCard task={data} />}
    />
  );
}
ReleaseReady

Launch plan

Milestones, owners, and final QA notes for the public release.

DesignReview

Brand board

Palette, type scale, and image direction for campaign pages.

ResearchNew

Research notes

Five customer interviews summarized into product opportunities.

GrowthDone

Metrics review

Activation moved up after the onboarding card refresh.

ProductPlanning

Roadmap

Small bets that improve feed performance and editorial control.

SupportOpen

Support themes

Repeated tickets grouped by install, styling, and virtualization.

Choose a component

GoalComponentImport
Simple responsive grids with no runtime measurementMasonrymasonix
Mixed-height cards that should visually balanceMasonryBalancedmasonix
Long feeds where rendering everything is expensiveMasonryVirtualmasonix/virtual

Practical defaults

  • Use itemKey for stable identity, especially when filtering or reordering.
  • Use columnWidth when the layout should adapt to available container width.
  • Use breakpoint maps when the product design calls for exact column counts.
  • Use getItemHeight when image dimensions are known before render.

Open the playground to compare column strategies, measured heights, virtualization, scroll seek, and imperative scrolling.

Next steps

On this page