# Message Scroller > Anchored, auto-following scroll container for chats. Import from `@aspyn-io/kit`. Scaffold source: `npx shadcn@latest add https://design.aspyn.io/r/message-scroller.json` ## Install ```tsx import { MessageScrollerProvider, MessageScroller, MessageScrollerViewport, MessageScrollerContent, MessageScrollerItem, MessageScrollerButton, useMessageScroller, } from "@aspyn-io/kit"; ``` ### Chat scroller A scroll container that follows the live edge, anchors each turn while its reply streams, and floats a jump-to-latest button when you scroll away. ```tsx {turns.map((turn) => ( {turn.text} ))} ``` ## Notes - Built on the @shadcn/react headless engine: anchored turns, streamed-reply following, prepended-history preservation, jump-to-message, and visibility tracking — all outside React state, so streaming doesn't re-render the list. - Mark each turn boundary (usually the user's message) with scrollAnchor. Give every item a stable messageId to enable scrollToMessage, prepend preservation, and visibility tracking. - Drive it imperatively with useMessageScroller() (scrollToMessage / scrollToEnd / scrollToStart); read useMessageScrollerScrollable() and useMessageScrollerVisibility() for jump buttons and outlines. Pass aria-busy on the content while streaming. - Not virtualized by design. For very large transcripts, let the viewport own scrolling and render rows with TanStack Virtual.