How alebl/magic-the-gathering-deckforge works
Purpose and Runtime
MTG Deck Forge is a local-first Magic: The Gathering card search, deck-building, analysis, proxy-printing, and playtest application. The primary runtime is a React 19/TypeScript renderer built by Vite; it runs either in a browser or inside Electron. Electron’s privileged boundary is defined by electron/index.ts and electron/preload.ts.
Application Composition and Entry Points
The renderer starts at src/main.tsx, mounts the application in src/App.tsx, and is framed by shared navigation/layout in src/components/layout/RootLayout.tsx. Domain UI is organized around card collection, deck editing, statistics, and playtesting rather than route-specific server endpoints. Shared types provide the central domain model: src/types/Card.ts, src/types/Deck.ts, and src/types/Playtest.ts.
Card Discovery and Collection
Card discovery is driven by debounced Scryfall-backed search and filter state through src/hooks/useCardSearch.ts and src/hooks/useSearchFilters.ts; results render through src/components/card/CardGrid.tsx and card details/actions through src/components/card/CardDetailModal.tsx. Collection ownership and filtering form a separate local concern in src/hooks/useCollection.ts, src/hooks/useCollectionOwnership.ts, and src/components/collection/CollectionManager.tsx. This boundary keeps remote card metadata distinct from user-owned inventory.
Deck Lifecycle and Persistence
Deck editing is centered on src/components/deck/DeckEditWorkspace.tsx, with global selected-deck and deck-list state in src/store/useDeckStore.ts. High-level lifecycle actions—create/edit/save/load/delete—are coordinated in src/hooks/useDeckManager.ts and src/hooks/useDeckActions.ts. Persistent local storage is configured in src/db/database.ts, while deck interchange/version capabilities live in src/services/deckImportService.ts, src/services/deckShare.ts, and src/services/deckVersionService.ts. Decks can therefore flow between UI state, IndexedDB, and import/export files without requiring an application backend.
Validation, Suggestions, and Analytics
Pure domain calculations sit behind the editing UI: legality and deck rules in src/utils/deckValidator.ts, deck metrics in src/utils/deckStatistics.ts, and automated recommendations in src/utils/deckSuggestions.ts. Their visual consumers are src/components/deck/DeckValidationBadge.tsx, src/components/stats/DeckStats.tsx, and src/components/deck/DeckSuggestionsModal.tsx. Scryfall is also an external legality/data authority, while local calculations provide immediate deck feedback.
Tokens, Printing, and Playtesting
Token requirements are derived from deck card data through src/hooks/useDeckTokens.ts and managed in src/components/deck/DeckTokensTab.tsx. Proxy-print configuration and output are handled by src/hooks/useProxyPrint.ts and src/components/deck/DeckProxyPrint.tsx. The playtest simulator has isolated interaction state in src/components/playtest/PlaytestContext.tsx, behavior in src/hooks/usePlaytestSimulator.ts, and its primary workspace in src/components/playtest/PlaytestSimulator.tsx; it consumes an assembled deck but models transient gameplay separately from persisted deck data.
Cross-Cutting Boundaries
Localization is initialized in src/plugins/i18n.ts with language catalogs in src/locales/en.ts, src/locales/es.ts, and src/locales/pt.ts. Application-level preferences include collection settings in src/store/useCollectionSettings.ts and browser persistence keys in src/constants/storage.ts. Network availability is surfaced through src/hooks/useOnlineStatus.ts, important because card search and legality checks depend on the external Scryfall API, while decks and collections remain available from local IndexedDB.
Main entry points: useDeckStore.ts Deck store · RootLayout.tsx Root layout · App.tsx Application shell · DeckEditWorkspace.tsx Deck editor
Components 20
React renderer
Local-first user interface and domain workflows.
- Renderer entry
src/main.tsx - Application shell
src/App.tsx - Root layout
src/components/layout/RootLayout.tsx - Card search · Debounced Scryfall search and filter state.
src/hooks/useCardSearch.ts - Card browser · Search results and card actions.
src/components/card/CardGrid.tsx - Collection manager · Separates owned inventory from card metadata.
src/components/collection/CollectionManager.tsx - Deck editor
src/components/deck/DeckEditWorkspace.tsx
Deck domain
Deck state, lifecycle, and local persistence.
- Deck store · Selected deck and deck-list state.
src/store/useDeckStore.ts - Deck lifecycle · Coordinates create, edit, save, load, and delete actions.
src/hooks/useDeckManager.ts - Local database · Persistent local deck storage.
src/db/database.ts - Deck interchange · Import/export, sharing, and version capabilities.
src/services/deckImportService.ts
Deck tools
Derived deck capabilities and isolated simulators.
- Deck validation · Pure legality and deck-rule calculations.
src/utils/deckValidator.ts - Deck analytics · Statistics and automated recommendations.
src/utils/deckStatistics.ts - Deck feedback UI · Visualizes validation, metrics, and suggestions.
src/components/stats/DeckStats.tsx - Token planner · Derives and manages token requirements.
src/hooks/useDeckTokens.ts - Proxy printing · Configures and produces proxy output.
src/hooks/useProxyPrint.ts - Playtest simulator · Isolated gameplay state for an assembled deck.
src/components/playtest/PlaytestSimulator.tsx
Platform services
Desktop boundary, localization, and external data.
- Scryfall API · Remote card metadata and legality authority.
- Electron boundary · Privileged desktop integration boundary.
electron/index.ts - Localization · Initializes language catalogs.
src/plugins/i18n.ts
Connections 22
- Renderer entry → Application shell: mounts
- Application shell → Root layout: frames
- Root layout → Card browser: hosts
- Root layout → Collection manager: hosts
- Root layout → Deck editor: hosts
- Card browser → Card search: uses
- Card search → Scryfall API: searches
- Collection manager → Local database: persists ownership
- Deck editor → Deck store: edits
- Deck editor → Deck lifecycle: invokes lifecycle
- Deck lifecycle → Deck store: updates
- Deck lifecycle → Local database: saves and loads
- Deck interchange → Local database: imports and exports
- Deck store → Deck validation: deck data
- Deck store → Deck analytics: deck data
- Deck validation → Deck feedback UI: legality
- Deck analytics → Deck feedback UI: metrics and suggestions
- Deck store → Token planner: deck cards
- Deck store → Proxy printing: deck contents
- Deck store → Playtest simulator: assembled deck
- Application shell → Localization: initializes
- Electron boundary → Renderer entry: hosts renderer