
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
react-anchorlist
Advanced tools
High-performance virtualized lists for React, optimized for chat and infinite feeds.
No flicker when prepending older messages. Stable scroll. Simple API.
npm install react-anchorlist
followOutput and declarative scroll commandsResizeObserverimport { VirtualList } from "react-anchorlist"
<VirtualList
data={tickets}
computeItemKey={(_, item) => item.id}
itemContent={(_, item) => <TicketRow ticket={item} />}
onEndReached={loadMore}
style={{ height: "100%" }}
/>
import { useState } from "react"
import { ChatVirtualList } from "react-anchorlist"
import type { ChatScrollModifier } from "react-anchorlist"
const [scrollModifier, setScrollModifier] = useState<ChatScrollModifier | null>(null)
<ChatVirtualList
data={messages}
computeItemKey={(_, item) => item._id}
itemContent={(_, item) => <Message data={item} />}
scrollModifier={scrollModifier}
followOutput="auto"
onStartReached={async () => {
// 1) tell the list to preserve anchor
setScrollModifier({ id: `prepend-${Date.now()}`, type: "prepend" })
// 2) prepend older messages in your state
await loadOlderMessages()
}}
onAtBottomChange={setIsAtBottom}
style={{ height: "100%" }}
/>
When data changes, control scroll behavior with scrollModifier:
type ChatScrollModifier =
| { id: string | number; type: "prepend" }
| { id: string | number; type: "append"; behavior?: "auto" | "smooth"; ifAtBottomOnly?: boolean }
| { id: string | number; type: "items-change" }
| { id: string | number; type: "jump-to-key"; key: string | number; align?: "start" | "center" | "end"; behavior?: ScrollBehavior }
id must be unique for each command.prepend keeps viewport position stable while older messages are added on top.append can auto-scroll to bottom.jump-to-key scrolls to one specific item.import {
ChatVirtualList,
VirtualList,
useChatVirtualizer,
usePagination,
} from "react-anchorlist"
ChatVirtualList most-used propsdata, itemContent, computeItemKey (required)scrollModifier (ChatScrollModifier | null)followOutput ("auto" | "smooth" | false, default: "auto")onStartReached, onEndReachedstartReachedThreshold and endReachedThreshold (default: 300)onAtBottomChangeestimatedItemSize (default: 80)overscan (default: 20)VirtualList most-used propsdata, itemContent, computeItemKey (required)onEndReachedendReachedThreshold (default: 300)estimatedItemSize (default: 60)overscan (default: 20)ChatVirtualList ref handlelistRef.current?.scrollToBottom()
listRef.current?.scrollToIndex(42, { align: "center", behavior: "smooth" })
listRef.current?.scrollToKey("msg-123", { align: "center" })
listRef.current?.getScrollTop()
listRef.current?.isAtBottom()
usePagination hook (optional helper)import { useEffect } from "react"
import { usePagination, ChatVirtualList } from "react-anchorlist"
const { items, hasPrevPage, loadPrevPage, loadingMore, refresh } = usePagination({
fetcher: async (page) => {
const res = await api.get(`/messages?page=${page}&per_page=50`)
return {
data: res.messages,
hasNextPage: res.pagination.current_page < res.pagination.last_page,
hasPrevPage: res.pagination.current_page > 1,
currentPage: res.pagination.current_page,
}
},
direction: "prepend",
getKey: (msg) => msg._id,
})
useEffect(() => {
refresh() // load initial page
}, [refresh])
<ChatVirtualList
data={items}
computeItemKey={(_, item) => item._id}
itemContent={(_, item) => <Message data={item} />}
onStartReached={hasPrevPage ? loadPrevPage : undefined}
components={{
Header: () => (loadingMore ? <Spinner /> : null),
}}
/>
computeItemKey.itemContent lightweight.estimatedItemSize.overscan low unless you need smoother very fast scrolling.scrollModifier over deprecated APIs (prepareAnchor, scrollToMessageKey).OffsetMap: stores cumulative offsets per itemResizeObserver: updates real row heightsIf your goal is npm discovery, keywords belong in package.json (not only in README text).
Suggested scope for this lib:
reactvirtual-listvirtualizationvirtual-scrollchatinfinite-scrollscroll-anchorUse this prompt in ChatGPT/Claude/Cursor/GitHub Copilot Chat:
You are a senior React engineer. Integrate the npm library `react-anchorlist` into my app.
Context:
- Stack: [React version + framework]
- Data type: [message/ticket/feed item shape]
- Item unique key: [id field]
- List container height strategy: [fixed/flex/full-screen]
Goal:
Implement a production-ready virtualized list with smooth scrolling and correct pagination behavior.
Requirements:
1) Use `ChatVirtualList` for chat-like UX (prepend older items at top).
2) Use stable `computeItemKey`.
3) Use `scrollModifier` commands correctly:
- before loading older items: `{ id: uniqueId, type: "prepend" }`
- when appending new realtime items: use append/items-change behavior when appropriate
- use `jump-to-key` for "scroll to message"
4) Keep `followOutput="auto"` and expose `onAtBottomChange`.
5) Wire `onStartReached` and/or `onEndReached` to my pagination functions.
6) Add proper TypeScript types.
7) Include minimal CSS/container setup so scrolling works (`height` + `overflow`).
8) Avoid deprecated APIs (`prepareAnchor`, `scrollToMessageKey`) unless migration support is explicitly requested.
Deliverables:
- Full component code ready to paste.
- State management for `scrollModifier`.
- Example handlers: `loadOlderMessages`, `loadNewerMessages`.
- Brief explanation of why the scroll stays stable on prepend.
- Optional: a second example using `VirtualList` for non-chat pages.
Project data to use:
- Messages state variable: [name here]
- Pagination function names: [names here]
- Message row component name: [name here]
Return clean, runnable code with no placeholders left.
MIT
FAQs
High-performance chat virtualizer for React — no flicker, no hacks
The npm package react-anchorlist receives a total of 2,150 weekly downloads. As such, react-anchorlist popularity was classified as popular.
We found that react-anchorlist demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.