Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:
The "Hold'em or Fold'em Poker" project is a web-based poker game built using Next.js 15, React 19, and TypeScript. The architecture emphasizes a clean separation of concerns, with a modular, framework-agnostic poker engine handling the core game logic, and a component-driven frontend managing the user interface and state. This design facilitates scalability and maintainability.
The application is structured as a Single Page Application (SPA), where the main view transitions are managed by a state machine within the root Home component. It leverages modern frontend technologies, including Tailwind CSS for styling, Radix UI for accessible component primitives, and React Context for state management across different features like tournaments and real-time communication.
Core Technologies
The project is built on a modern JavaScript stack. The key dependencies defined in package.json provide insight into the foundational technologies used.
| Dependency | Version | Description |
|---|---|---|
next | 15.5.7 | The React framework for server-side rendering and static site generation. |
react | 19.1.0 | The core library for building the user interface. |
typescript | ^5 | Provides static typing for the codebase. |
tailwindcss | ^4.1.9 | A utility-first CSS framework for styling. |
@radix-ui/react-* | latest | A collection of unstyled, accessible UI component primitives. |
lucide-react | ^0.454.0 | A library of simply designed icons. |
class-variance-authority | ^0.7.1 | Manages component variants. |
tailwind-merge | ^2.5.5 | Utility to merge Tailwind CSS classes without style conflicts. |
Sources: package.json:11-53
Application Structure
The application follows a standard Next.js app directory structure. The overall architecture is composed of a main view controller, a set of UI components, a styling system, and a decoupled game logic engine.
Entry Point and View Routing
The primary entry point is app/page.tsx, which acts as a state machine to control which view is rendered to the user. It uses a currentView state variable of type PageView to switch between different screens like the lobby, table selection, and the poker table itself.
Sources: app/page.tsx:10-14
This diagram shows the flow of user navigation between different views, managed by the state in app/page.tsx.
Sources: app/page.tsx:16-89
Root Layout and Context Providers
The app/layout.tsx file defines the root layout for the entire application. It wraps all child components with global context providers, making shared state available throughout the component tree.
WebRTCProvider: Suggests the use of WebRTC for real-time, peer-to-peer communication, likely for game actions and chat.TournamentProvider: Manages state related to tournament play, such as blind levels and player rankings.
Sources: app/layout.tsx:26-28
This setup ensures that components like HomeLobby or ChatPanel can access shared player and game data through custom hooks (useWebRTC, useTournament, useChat).
Sources: components/lobby.tsx:12, components/chat-panel.tsx:18
Poker Game Engine
The core game logic is encapsulated within lib/poker-engine.ts. This module is written in pure TypeScript and has no dependencies on React or the UI, making it a portable and independently testable engine. It is responsible for managing the game state, processing player actions, and determining winners.
Sources: lib/poker-engine.ts
Core Data Structures
The engine relies on a set of interfaces to model the game state. The GameState interface is the central object, tracking everything from the current phase to player details.
This class diagram illustrates the relationships between the main data structures in the poker engine.
Key Functions
The engine exposes a set of pure functions to manage the game lifecycle.
| Function | Description |
|---|---|
initializeGame() | Creates the initial GameState, deals cards, and sets up players. |
startNewHand() | Resets the table for a new hand, rotates the dealer, posts blinds, and deals new cards. |
processAction() | Takes a player action (fold, check, call, raise, all-in) and updates the GameState. |
advancePhase() | Moves the game to the next phase (e.g., from pre-flop to flop). |
evaluateHand() | Evaluates a 7-card hand (2 hole + 5 community) to find the best 5-card combination. |
evaluateOmahaHand() | Evaluates an Omaha hand (exactly 2 hole + 3 community). |
determineWinners() | Compares hands of all active players at showdown to find the winner(s). |
Sources: lib/poker-engine.ts:381, lib/poker-engine.ts:409, lib/poker-engine.ts:468, lib/poker-engine.ts:553, lib/poker-engine.ts:110, lib/poker-engine.ts:121, lib/poker-engine.ts:326
Game Flow Logic
The game progresses through distinct phases, managed by the advanceTurn and advancePhase functions. A betting round concludes when all active players have acted and contributed an equal amount to the pot.
This flowchart shows the progression of a single poker hand.
Sources: lib/poker-engine.ts:553-597
The engine also supports different game modes (sng, omaha, allin) by checking the gameMode property within the GameState. For example, it deals 4 cards for Omaha and restricts actions in "all-in or fold" mode.
Sources: lib/poker-engine.ts:50-52, lib/poker-engine.ts:482-488
Styling and Theming
The application uses Tailwind CSS for its utility-first styling approach. A custom theme is defined in app/globals.css, which includes support for both light and dark modes through CSS variables.
CSS Variables
The theme is highly customizable via a set of CSS variables defined in the :root and .dark selectors. This allows for consistent branding and easy theme switching.
| Variable | Light Mode Value | Dark Mode Value | Purpose |
|---|---|---|---|
--background | oklch(1 0 0) | oklch(0.145 0 0) | Main page background color. |
--foreground | oklch(0.145 0 0) | oklch(0.985 0 0) | Main text color. |
--card | oklch(1 0 0) | oklch(0.145 0 0) | Background color for card components. |
--primary | rgb(88, 88, 109) | oklch(0.985 0 0) | Primary interactive element color. |
--destructive | oklch(0.577 0.245 27.325) | oklch(0.396 0.141 25.723) | Color for destructive actions (e.g., errors). |
--chart-4 | oklch(0.828 0.189 84.429) | oklch(0.627 0.265 303.9) | An accent color used for highlights. |
--radius | 0.625rem | 0.625rem | Base border radius for elements. |
Sources: app/globals.css:5-35, app/globals.css:42-72
The project also uses clsx and tailwind-merge utilities to conditionally and safely combine CSS classes, preventing style conflicts and improving code readability in components.
Sources: package.json:32-33, components/table-selection.tsx:162
Conclusion
The architecture of "Hold'em or Fold'em Poker" is robust and well-considered for a modern web application. By separating the core game logic into a standalone engine, the developers have created a system that is easy to test, maintain, and potentially reuse in other contexts. The frontend is built with industry-standard tools like Next.js and Tailwind CSS, providing a solid foundation for a rich and interactive user experience. The use of context providers for state management and a component-based structure ensures that the application remains organized and scalable as new features are added.