The Ultimate Pokédex - A constellation of all officially licensed canon knowledge of the Pokémon franchise.
pkdx++ is building a highly integratable, platform-agnostic Pokédex that combines:
- Video Games: Core series data, stats, moves, abilities, locations
- TCG: Trading card game cards and sets
- Anime: Episode appearances and character info
- And more: Movies, manga, merchandise, artwork
Live Demo: https://pkdx-plus-plus.netlify.app
- Framework: Next.js 16 with App Router
- Language: TypeScript (strict mode)
- Styling: Tailwind CSS
- UI Library: shadcn/ui (Radix UI primitives + CVA + Tailwind)
- Components: Four-tier system — Tier 0 design principles (1D/2D/3D), shadcn/ui primitives, Vivid design components, Feature components
- Database: PostgreSQL + Prisma
- Hosting: Netlify (with @netlify/plugin-nextjs)
- Testing: Jest + React Testing Library (80% coverage threshold)
- Node.js >= 18.0.0
- npm or yarn
# Clone the repository
git clone https://github.com/seandonn-boston/PkdxPlusPlus.git
cd PkdxPlusPlus
# Install dependencies
npm install
# Run development server
npm run devOpen http://localhost:3000 to view the app.
| Script | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Create production build |
npm run start |
Start production server |
npm run lint |
Run ESLint |
npm run format |
Format code with Prettier |
npm run format:check |
Check code formatting |
npm test |
Run tests |
npm run test:watch |
Run tests in watch mode |
npm run test:coverage |
Run tests with coverage report |
npm run test:ci |
Run tests for CI environment |
npm run netlify:dev |
Run Netlify dev server |
npm run netlify:build |
Build for Netlify environment |
This project is configured for deployment on Netlify using the @netlify/plugin-nextjs plugin.
- Connect Repository: Link your GitHub repository to Netlify
- Configure Environment Variables:
DATABASE_URL: Your PostgreSQL connection string (Neon recommended)
- Deploy: Netlify will automatically build and deploy on push
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string |
NEXT_PUBLIC_SITE_URL |
No | Custom domain URL for SEO/sitemap |
NEXT_PUBLIC_DISABLE_IMAGE_OPTIMIZATION |
No | Set to "true" to disable image opt |
For serverless deployments on Netlify, we recommend:
- Neon - Serverless PostgreSQL with connection pooling
- Supabase - PostgreSQL with built-in APIs
- PlanetScale - MySQL-compatible serverless database
# Install Netlify CLI globally
npm install -g netlify-cli
# Run the Netlify dev server
npm run netlify:dev
# Build for Netlify
npm run netlify:buildsrc/
├── app/ # Next.js App Router pages
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Home page
│ ├── globals.css # Global styles + shadcn/ui CSS variables
│ ├── dex/ # National Pokédex (list + detail)
│ ├── moves/ # Movedex (list + detail)
│ ├── abilities/ # Abilitydex (list + detail)
│ ├── items/ # Itemdex (list + detail)
│ ├── locations/ # Locationdex (list + detail)
│ ├── natures/ # Naturedex (list + detail)
│ ├── trainers/ # Trainerdex (list + detail)
│ ├── types/ # Typedex (list + detail)
│ ├── timeline/ # Pokemon timeline
│ ├── constellation/ # 3D WebGL visualizer
│ └── api/ # API routes
├── components/
│ ├── ui/ # Tier 1: shadcn/ui primitives (Button, Card, Tabs, etc.)
│ ├── vivid/ # Tier 2: Vivid design system (TypeBadge, FloatingCard, etc.)
│ ├── features/ # Tier 3: Domain components (StatBar, EvolutionChain, etc.)
│ ├── layout/ # Header, Footer, Navigation, SearchCommand
│ ├── constellation/ # 3D visualizer components
│ └── shared/ # Cross-cutting (ErrorBoundary, ThemeProvider, etc.)
├── lib/
│ ├── db.ts # Prisma client singleton
│ ├── pokeapi.ts # PokéAPI client with caching
│ ├── queries/ # Hyperdex data access layer
│ │ ├── types.ts # CardData interfaces
│ │ ├── pokemon.ts # Pokemon queries
│ │ ├── evolutions.ts # Evolution queries
│ │ ├── moves.ts # Move queries
│ │ ├── abilities.ts # Ability queries
│ │ ├── type-queries.ts # Type queries
│ │ ├── locations.ts # Location queries
│ │ ├── trainers.ts # Trainer queries
│ │ ├── items.ts # Item queries
│ │ └── natures.ts # Nature queries
│ ├── constellation/ # 3D graph logic
│ ├── journey/ # Journey tracking
│ ├── type-effectiveness.ts
│ └── utils.ts
├── types/ # TypeScript definitions
└── data/ # Static data and importers
└── trainers-seed.json
schemas/ # Architecture & design specifications
e2e/ # End-to-end Playwright tests
This project maintains an 80% code coverage threshold across statements, branches, functions, and lines. Tests are co-located with their source files (e.g., Component.tsx has Component.test.tsx in the same directory).
# Run all tests
npm test
# Run with coverage report
npm run test:coverage
# Run in watch mode during development
npm run test:watchAll metrics must meet the 80% minimum threshold:
| Category | Threshold |
|---|---|
| Statements | 80% |
| Branches | 80% |
| Functions | 80% |
| Lines | 80% |
This project uses a four-tier design system built on shadcn/ui, with Tier 0 defining the foundational design principles:
| Tier | Location | Purpose | Focus |
|---|---|---|---|
| Tier 0: Principles | schemas/design-system.spec.md |
Design constraints across 1D (scale, rhythm), 2D (layout, composition), 3D (depth, elevation), XR (presence, embodied interaction) | The "why" — no magic numbers |
| Tier 1: Primitives | src/components/ui/ |
Accessible building blocks from shadcn/ui + Radix UI | Button, Card, Dialog, Tabs, Badge, Table, Select |
| Tier 2: Vivid Design | src/components/vivid/ |
Compose Tier 1 with the Vivid design system (type colors, glow, depth) | FloatingCard, TypeBadge, OrganicInput, FilterPills |
| Tier 3: Features | src/components/features/ |
Compose Tier 1 + Tier 2 for domain-specific Pokemon UI | StatBar, StatRadar, EvolutionChain, LearnsetTable |
Additional component groups: layout/ (Header, Footer, Navigation), constellation/ (3D WebGL), shared/ (ErrorBoundary, ThemeProvider).
| Component | Tier | Purpose |
|---|---|---|
| StatBar | 3 | Animated stat bars with color coding |
| StatRadar | 3 | Hexagonal radar chart for stats |
| Tabs (shadcn) | 1 | Accessible tabbed navigation |
| EvolutionChain | 3 | Interactive evolution paths |
| TypeEffectiveness | 3 | Type matchup chart |
| LearnsetTable | 3 | Sortable move tables (shadcn Table) |
| SpriteGallery | 3 | Filterable sprite viewer |
| CryPlayer | 3 | Audio playback for Pokemon cries |
| TypeBadge | 2 | Pokemon type styling (shadcn Badge) |
| FloatingCard | 2 | Neumorphic card with glow (shadcn Card) |
The 3D constellation visualization at /constellation uses a force-directed graph layout with over 1000 nodes representing Pokemon, types, abilities, moves, and locations. Below are the core mathematical equations that govern the simulation.
The graph uses a physics-based simulation where nodes repel each other while connected nodes attract. The system iterates until reaching equilibrium.
Nodes repel each other using an inverse-square law, similar to electrostatic repulsion:
F = strength / distance²
| Parameter | Default | Description |
|---|---|---|
strength |
-150 | Negative = repulsive force |
distanceMax |
800 | Maximum interaction range |
Connected nodes attract each other based on their distance from the target length:
F = strength × weight × (currentDistance - targetDistance)
| Parameter | Default | Description |
|---|---|---|
linkDistance |
80 | Desired edge length |
linkStrength |
0.1 | Base attraction strength |
weight |
0.5–2.0 | Varies by relationship type |
Edge weights by relationship:
- Evolution chains:
2.0(strongest) - Type effectiveness:
1.5 - Has type:
1.0 - Found at location:
0.6 - Learns move:
0.5(weakest)
Prevents node overlap using quadratic repulsion when spheres intersect:
collisionRadius = nodeSize × baseRadius
| Parameter | Default | Description |
|---|---|---|
baseRadius |
25 | Base collision sphere |
strength |
0.8 | Overlap force magnitude |
The simulation uses alpha decay and velocity damping to reach equilibrium:
α_next = α × (1 - alphaDecay)
v_next = v × (1 - velocityDecay)
| Parameter | Default | Description |
|---|---|---|
alphaDecay |
0.0228 | ~2.3% energy reduction per tick |
velocityDecay |
0.4 | 40% velocity damping per tick |
iterations |
300 | Physics ticks before render |
Pokemon are initially positioned in a circular arrangement by type before force simulation begins:
angle = (2π × typeIndex) / 18
x = cos(angle) × radius
y = sin(angle) × radius
z = (generation - 5) × 30
| Radius | Pokemon Type |
|---|---|
| 150 | Mono-type Pokemon (inner ring) |
| 300 | Dual-type Pokemon (outer ring) |
The 18 Pokemon types are evenly distributed around the circle at 20° intervals.
distance = √((x₂ - x₁)² + (y₂ - y₁)² + (z₂ - z₁)²)
Edges are rendered as smooth curves using parametric Bézier equations:
B(t) = (1-t)²P₀ + 2(1-t)tP₁ + t²P₂
Where:
P₀= source node positionP₁= control point (curve direction)P₂= target node positiont= parameter from 0 to 1
Each edge is sampled at 10 segments (11 points) for smooth rendering.
Edges with many crossings are faded to reduce visual clutter:
opacity = max(0.15, 0.9 - (crossings / maxCrossings) × 0.75)
Heavily crossed edges fade to 15% opacity while isolated edges remain at 90%.
Mouse positions are converted to normalized [-1, 1] range for raycasting:
NDC.x = (mouseX / width) × 2 - 1
NDC.y = -(mouseY / height) × 2 + 1
The Y-axis is inverted because screen coordinates grow downward while NDC grows upward.
Camera transitions use cubic easing for natural deceleration:
eased = 1 - (1 - t)³
position = lerp(start, target, eased)
| Parameter | Value | Description |
|---|---|---|
ZOOM_DISTANCE |
80 | Final distance from node |
ZOOM_DURATION |
800ms | Animation length |
For efficient raycasting, nodes are partitioned into a 3D grid:
cellKey = floor(x/50) + "," + floor(y/50) + "," + floor(z/50)
This reduces raycast complexity from O(n) to O(queryRadius³).
size = NODE_BASE_SIZE × nodeSize × SCALE_FACTOR × stateMultiplier
| Constant | Value |
|---|---|
NODE_BASE_SIZE |
8 |
SCALE_FACTOR |
0.6 |
| Selected multiplier | 1.5× |
| Visited multiplier | 1.2× |
Size multipliers by entity type:
- Type nodes:
3.0×(major hubs) - Location:
1.5× - Trainer:
1.25× - Pokemon:
1.0× - Ability:
0.75× - Move:
0.5×
Nodes use a custom fragment shader for soft edges:
edgeFactor = 1.0 - abs(dot(normal, viewDirection))
opacity = mix(0.8, 0.1, edgeFactor)Center opacity is 80%, fading to 10% at silhouette edges.
| Technique | Impact |
|---|---|
| Instanced rendering | Single draw call for all nodes |
| Spatial hashing | O(1) node lookup for raycasting |
| Frame rate cap | Max ~120fps (8ms minimum delta) |
| Raycast debounce | Max 20 raycasts/second |
| Quality presets | 4–48 sphere segments based on device |
| Document | Purpose |
|---|---|
| ROADMAP.md | Project roadmap and task tracking |
| docs/SITEMAP.md | Site map and page status |
| CLAUDE.md | Claude Code project directives |
| schemas/ | Architecture & design specifications |
| Spec | Description |
|---|---|
architecture.spec.md |
5-layer architecture overview |
database.spec.md |
PostgreSQL + Prisma schema |
components.spec.md |
Component design patterns |
design-system.spec.md |
Design tokens and visual system |
ui-library-integration.spec.md |
shadcn/ui component library overhaul plan |
spatial-computing.spec.md |
Multi-device VR/AR constellation |
See ROADMAP.md for current development status and task tracking.
This project uses a multi-dimensional review methodology to ensure comprehensive quality. Issues are evaluated across 8 interconnected dimensions:
| # | Dimension | Focus |
|---|---|---|
| 1 | Technical Stack | Code quality, architecture, security, performance |
| 2 | Capabilities | Feature completeness, accessibility, UX |
| 3 | Subject Matter | Pokémon data accuracy and completeness |
| 4 | Developer Experience | Documentation, tooling, onboarding |
| # | Dimension | Focus |
|---|---|---|
| 5 | Operational Readiness | Monitoring, reliability, deployment safety |
| 6 | Scalability | Database performance, caching, bundle size |
| 7 | Content Strategy | Data freshness, i18n, SEO |
| 8 | User Journey | Navigation, user flows, engagement |
Problems don't exist in isolation—a bug in one dimension often impacts others:
- Technical issues → Break capabilities → Frustrate user journeys
- Missing data → Cause query errors → Create debugging challenges
- Poor DX → Slow development → Delay capability improvements
Quality enforcement is handled by the .github/ agent and instruction system.
We welcome contributions! Please see our development workflow:
- Fork the repository
- Create a feature branch following the naming convention:
<author>/<type>-<description> - Make your changes following the coding standards in CLAUDE.md
- Run the full verification chain:
npm i && npm run db:generate && npm run lint && npm run format:check && npm run test:coverage && npm run build - Submit a pull request
For detailed contribution guidelines, see the ROADMAP.md.
MIT License - See LICENSE for details.
Note: Pokemon and all related properties are trademarks of Nintendo, Game Freak, and The Pokemon Company. This project is a fan-made encyclopedia and is not affiliated with or endorsed by the official Pokemon franchise.
Built with Next.js, TypeScript, and Tailwind CSS