Home /work/
Memory Card Game
BUILTMar 2026Live

Memory Card Game

A Pokémon-themed memory game built with Next.js 16 and TypeScript. Twelve cards are fetched live from the PokeAPI, reshuffle after every click, and track your current and best score.

Role
Frontend Development
Timeline
March 2026
Deployed on
Vercel
Made with
  • Next.js 16
  • React 19
  • TypeScript
  • Tailwind CSS
  • PokeAPI
  • Vercel
Cards per round
12
Pokémon pool
1000+
Memory Card Game

Overview

The project

A Pokémon-themed take on the classic memory game, built as a self-directed practice project. On every load it pulls twelve random Pokémon from the public PokeAPI, then the rules are simple: click each card once without ever clicking the same one twice. The catch is that the whole board reshuffles after every pick, so you can't lean on position, only memory. It's a small project, but it's where I got comfortable with real API data, chaining fetches with Promise.all(), and keeping React state immutable while the UI changes on every interaction.

This is a free, non-commercial practice project. Pokémon names and artwork are trademarks and © of Nintendo, Creatures Inc., GAME FREAK inc. and The Pokémon Company, and the project isn't affiliated with or endorsed by any of them. Card data and sprites come from PokeAPI.

What's inside

Features & pages

Pokémon card grid

12 random Pokémon fetched from the PokeAPI on every load

Shuffle on click

Cards reshuffle after each pick so position can't be memorized

Score board

Tracks your current score and remembers your best score

Win & game-over states

Win by clicking all 12 without repeats; repeat one and it's game over

What was hard

Challenges & solutions

Problem

Clicking the same Pokémon twice had to end the game, so every already-picked card needed tracking without slowing down as the round went on.

Solution

Stored clicked card IDs in a JavaScript Set for O(1) duplicate lookups instead of scanning an array on every click.

Problem

Each PokeAPI list item only returns a name and a URL; the artwork lives behind a second request per Pokémon.

Solution

Chained a second fetch per card and ran all 12 in parallel with Promise.all(), so the board loads in one round trip instead of twelve sequential ones.

Problem

Reshuffling the board on every click risked mutating React state directly and dropping re-renders.

Solution

Always built a new array (spread + sort) and set it into state, keeping state immutable so React re-rendered reliably.

Built with

Tech stack

Next.js 16

Framework (App Router)

React 19

UI + hooks

TypeScript

Type safety

Tailwind CSS

Styling

PokeAPI

Card data

Vercel

Deployment

Other work