Tic-Tac-Toe with React TypeScript and Tailwindcss - sessionStorage

Solution retrospective
What I'm most proud of
TypeScript is finally starting to click. After a few projects, I feel more confident with props, interfaces, and wiring components together to get the behavior I want.
The highlight of this project was definitely the game logic. The matrix-based approach for win detection (WIN_COMBS as an array of index triplets) was completely new to me. I worked through it step by step with AI assistance, and building getCpuMove — watching the CPU actually play autonomously, blocking moves and going for the win — felt almost magical.
I also pushed through all the bonus features: sessionStorage for state persistence, the restart modal, hover states on cells... Everything works as intended, and that feels good.
What I'd do differently
Add tests. This project had real game logic — win detection, CPU decisions, turn management — and I relied entirely on manual testing. Next time, I want to set up a proper testing workflow (likely with Vitest) to catch edge cases earlier and build confidence when refactoring.
What challenges did you encounter, and how did you overcome them?CPU logic and win detection
The biggest challenge was building the CPU's autonomous play. The solution came from WIN_COMBS — an array of 8 winning triplets (indices). This made it possible to check for a winning move, then for a blocking move, then fall back to a random cell. Simple priority chain, but powerful result.
State ownership
Figuring out what lives in Cell vs Game was tricky at first. Once I understood that turn alternation and board state belong in Game, and Cell just receives props and reports clicks, everything clicked into place.
Modal architecture
I chose to create two separate modal components (Modal for round results, RestartModal for the restart confirmation) rather than one generic modal with more props. It keeps things readable and avoids unnecessary complexity for a project this size.
Design system upfront
I spent time early on building utility classes and text presets matching the Figma spec. That investment paid off — styling was smooth for the rest of the project.
What specific areas of your project would you like help with?As always, thanks to anyone who takes the time to leave feedback or review the code — it's incredibly valuable to me. I'm self-taught and currently looking for my first frontend developer position, so external perspective matters a lot.
What I'm most curious about:
- Red flags — Is there anything in my code that would raise concerns in a professional context?
- Industry standards — Does this project follow common conventions? Are there patterns or practices that teams in larger companies rely on that I might be missing?
- Commit hygiene — Is my commit history clear and logical?
- Naming and architecture — Do my function names, component structure, and file organization make sense?
Basically: if something feels off to you, please tell me what it is and how to fix it. I'm here to learn.
Please log in to post a comment
Log in with GitHubCommunity feedback
No feedback yet. Be the first to give feedback on Thomas’s solution.
Join our Discord community
Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!
Join our Discord