mugen

Getting Started

Install mugen and render your first analytic virtualized list.

Install

npm install @wingleeio/mugen

Requires React 18.2 or 19.

Your first list

A list is two pieces:

  • useMugenVirtualizer({ items }) — a hook that creates and owns the list instance (its measurement engine and scroll position).
  • <MugenVList> — the component. You give it the instance, a getKey, and a render that returns each row as a tree of primitives.
import { , , ,  } from '@wingleeio/mugen';

interface Comment {
  : string;
  : string;
  : string;
}

export function ({  }: { : Comment[] }) {
  const  = ({ :  });
  return (
    <
      ={}
      ={() => .}
      // List-level text defaults — every <Text> inherits them (and can override).
      ="15px Inter"
      ={22}
      ="2xl"
      ={() => (
        < ={4} ={12}>
          < ="600 15px Inter">{.}</>
          <>{.}</>
        </>
      )}
    />
  );
}

Here's a list running — toggle between the preview and the code:

chat-list.tsx
loading preview…

That's a fully virtualized list. No react-virtuoso, no measure-on-mount, no layout shift — even with 100,000 comments, only the visible window mounts, and the scrollbar is exact from the first frame.

The item type is inferred

useMugenVirtualizer({ items }) infers the row type from items, and it flows through getKey and render. Pass it explicitly if you need to — useMugenVirtualizer<Comment>({ items }).

The font must be measurable

pretext measures against the browser's font engine, so font must be a named font in canvas shorthand ("16px Inter", "600 15px Inter"). system-ui is rejected — its metrics differ per OS, so heights would drift from what the user sees.

const :  = '16px Inter'; // ✓ measured against the font engine
const :  = '16px system-ui'; // type-ok, but throws at runtime (per-OS metrics)

If the font loads asynchronously (most web fonts do), mugen re-measures automatically once document.fonts settles — no layout shift.

Next

On this page