Getting Started
Install mugen and render your first analytic virtualized list.
Install
npm install @wingleeio/mugenRequires 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 theinstance, agetKey, and arenderthat 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:
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
- How it works — the single-source measurement model.
- Primitives — the vocabulary rows are built from.
- State & hooks —
useMugenState,useMugenMemo,useMugenEffect. - Scrolling —
instance.scrollToItem. - Recipes — chat, accordions, deep links.