Get Poke-Nex running on your local machine in just a few steps. This guide will walk you through cloning the repository, installing dependencies, and starting the development server.
Prerequisites
Before you begin, make sure you have:
Node.js 20+ installed on your machine
Package manager: npm, yarn, or pnpm (we recommend pnpm)
Git for cloning the repository
Installation
Clone the repository
Clone the Poke-Nex repository from GitHub: git clone https://github.com/codentide/poke-nex.git
cd poke-nex
Install dependencies
Install the project dependencies using your preferred package manager:
Start the development server
Production build
To create an optimized production build:
The build process pre-renders 1025+ Pokémon pages using Static Site Generation (SSG). This typically takes around 11-12 seconds thanks to parallel build workers.
Project structure
Understanding the project structure will help you navigate the codebase:
poke-nex/
├── src/
│ ├── app/ # Next.js App Router pages
│ │ ├── page.tsx # Home page (Pokemon gallery)
│ │ ├── pokemon/ # Pokemon detail pages
│ │ ├── favorites/ # Favorites page
│ │ └── calculator/ # Type calculator
│ ├── components/ # React components
│ │ ├── pokemon/ # Pokemon-specific components
│ │ └── calculator/ # Type calculator components
│ ├── services/ # Business logic layer
│ ├── adapters/ # Data transformation layer
│ ├── lib/ # Utilities and API fetchers
│ │ ├── api/ # PokeAPI fetchers
│ │ └── utils/ # Helper functions
│ ├── stores/ # Zustand state stores
│ ├── hooks/ # Custom React hooks
│ ├── types/ # TypeScript type definitions
│ └── constants/ # App constants
├── public/ # Static assets
└── next.config.ts # Next.js configuration
Example: Home page
Here’s how the home page fetches and displays the Pokémon list using Clean Architecture:
import { PokeGallery } from '@/components/pokemon'
import { getPokemonListGQL } from '@/services/pokemon.service'
export default async function Home () {
const { data : pokemonList , error } = await getPokemonListGQL ()
if ( error ) throw new Error ( JSON . stringify ( error ))
return (
< main className = "flex flex-col gap-8 min-h-screen py-12 px-[4%] md:px-[12%] lg:px-[20%]" >
< div className = "flex flex-col items-center gap-2 text-center" >
< h1 className = "text-4xl lg:text-6xl font-bold uppercase font-rajdhani text-zinc-300" >
Explore
</ h1 >
< p className = "text-zinc-500 text-md" >
Discover information and statistics about your favorite Pokémon .
</ p >
</ div >
< PokeGallery content = { pokemonList } />
</ main >
)
}
Example: Pokemon detail with SSG
Each Pokémon detail page is statically generated at build time:
src/app/pokemon/[slug]/page.tsx
export async function generateStaticParams () {
const { data } = await getPokemonList ()
if ( ! data ) return []
return data . map (({ name }) => ({ slug: name }))
}
export default async function PokemonPage ({ params } : Props ) {
const { slug } = await params
const { data : pokemon , error } = await getPokemonDetail ( slug )
if ( error || ! pokemon ) notFound ()
return < PokemonDetailView pokemon = { pokemon } />
}
Development tips
Use the type calculator at /calculator to explore Pokémon type effectiveness and weaknesses.
The favorites system persists to localStorage, so your collection is preserved across sessions.
View mode preferences (Grid vs Table) are stored in sessionStorage and reset when you close the browser tab.
Next steps
Explore features Learn about all 8 key features and how they work
Architecture guide Understand the Clean Architecture pattern
Component library Browse the reusable component catalog
API reference Explore the services, adapters, and hooks