Content & display
Virtual List / Windowing
Render only the visible window of a long list and recycle nodes as the user scrolls.
Also known as virtual scroll · windowed list · recycled list
Demo · not production-ready code
Prompt for AI
Pick a stack, copy a ready prompt, paste into Cursor / Claude / ChatGPT.
Your stack
Shapes the prompt you copy
React + Tailwind + shadcn/ui · EN
Stack: React + Tailwind + shadcn/ui. Use React with Tailwind CSS and shadcn/ui patterns (Radix-based primitives, cn(), class-first styling). Task: implement "Virtual List / Windowing". Virtualize the order list for up to 10k rows: render the visible window plus ~5 rows of overscan, a spacer for true scroll height, stable data ids as keys. Prefer fixed row height first; measure if heights vary. Skip virtualization under a few hundred rows. Anatomy: - viewport / window: The rows actually mounted. - spacer / total size: Keeps the scrollbar honest for the full dataset. - overscan: Extra rows above/below so fast scrolls don’t flash empty. - recycling: DOM nodes leave the window and host new data. Preferred API / pattern: `react-window / @tanstack/virtual / virtua` Keep scope minimal: only this UI pattern, match existing project style.
Acceptance checks
- ○Avoid: Virtualizing dozens of rows
- ○Avoid: Variable heights assumed fixed
- ○Avoid: Fast scroll white gaps
- ○Avoid: Keys are array indexes
- ○Avoid: Forgetting Ctrl/Cmd+F is broken
In plain wordsHow people search for it
“a huge list that still scrolls smooth because it only draws what’s on screen”“ten thousand rows without melting the browser”“recycling row DOM as I scroll instead of mounting everything”
AnatomyOpen for part names
- viewport / window
- The rows actually mounted.
- spacer / total size
- Keeps the scrollbar honest for the full dataset.
- overscan
- Extra rows above/below so fast scrolls don’t flash empty.
- recycling
- DOM nodes leave the window and host new data.
How to write itOpen for stack patterns
Web (HTML/CSS)
windowing libs / content-visibility: autoReact + Tailwind + shadcn/ui
react-window / @tanstack/virtual / virtuaSwiftUI
LazyVStack / List (lazy by default)Ant Design
virtual prop on Table/List / rc-virtual-listNotes
Not a widget—a strategy. DOM count kills long lists; windowing turns 10k rows into ~20. Cost: in-page find won’t see unmounted rows, a11y trees are partial, variable heights get hard. Don’t virtualize a 40-row table—that’s over-engineering.
Common mistakesHumans and models trip here
- Virtualizing dozens of rows: complexity with no payoff.
- Variable heights assumed fixed: scrollbar jumps and hit targets lie.
- Fast scroll white gaps: raise overscan and skeleton placeholders.
- Keys are array indexes: recycled rows keep the wrong checkbox state—use ids.
- Forgetting Ctrl/Cmd+F is broken: ship an explicit search field.
More failure symptoms on AI broke it.
Related patterns
Data TableA grid of rows and columns for comparing structured records.Skeleton ScreenPlaceholder shapes that mirror upcoming content so loading feels structured, not empty.Pull to RefreshPull a list past a threshold from the top to trigger a reload—mobile muscle memory.PaginationControls that split large result sets into numbered pages.
Spotted a wrong name or missing pattern?