A small side project built to explore virtualized lists in React. A standard technique for whenever I need to render large datasets without sacrificing performance.
Keeping experiences fast is a constant concern in frontend engineering. Rendering hundreds or thousands of DOM nodes at once tanks scroll performance and wastes memory. Virtualization solves this by only rendering the rows currently visible in the viewport, regardless of how large the full list is.
I wanted a hands-on project to put this into practice, so I built a Pokédex with all 1,028 Pokémon using TanStack Virtual for the virtualized list and TanStack Query for data fetching and caching.
- Virtualized list rendering ~15 rows at a time regardless of total count.
- Full list of 1,028 Pokémon fetched in a single request and cached permanently.
- Click any row to open a detail modal with official artwork, types, base stats, and quick facts.
- Detail fetches are cached per Pokémon and clicking the same one twice hits the cache reducing the need for extra API calls.
- Lightweight test coverage for utility functions, and key UI interactions.
- React + TypeScript — component-based UI development with type-safe props and state
- Vite — fast local development and optimized production builds
- TanStack Query — server state management and caching
- TanStack Virtual — row virtualization
- Tailwind CSS v4 — styling
- PokéAPI — free, open Pokémon data
- Vitest + Testing Library + Happy DOM — unit and component tests
# Install dependencies
npm install
# Start the dev server
npm run dev
# Run tests
npm test