GitHub Profile Explorer - Next.js, React, TypeScript, Apollo Client, GraphQL, TailwindCSS Fundamental Project 5
A modern, feature-rich web application to search and explore GitHub user profiles using the GitHub GraphQL API. Built with Next.js App Router, React, TypeScript, Tailwind CSS, Apollo Client, and shadcn/ui, this project demonstrates advanced state management, data visualization, responsive design, and a clean UI—ideal for learning full-stack web development, GraphQL, and modern React patterns.
- Live Demo: https://github-dev-explorer.vercel.app/
- Features
- Project Structure
- Technology Stack
- Getting Started
- Environment Variables
- Routes & API
- Components & Functionalities
- How GraphQL & Apollo Client Work
- Libraries & Dependencies
- Reusing Components
- Keywords
- License
- Search GitHub Users — Search by username using the GitHub GraphQL API
- User Profile — View avatar, name, bio, company, location, website, and profile link
- Statistics — Total repositories, followers, following, and gists in card layout
- Repository List — Filterable and sortable repo cards with language/topic badges
- Charts — Interactive bar charts: most used languages, popular repos, forked repos
- Theme Toggle — Light/dark mode with persistent preference
- Recent Searches — Quick access to previous searches in the navbar
- Toast Notifications — User feedback for invalid input and errors
- Loading Skeletons — Smooth loading experience
- Responsive UI — Mobile, tablet, and desktop support
- TypeScript — Type-safe codebase
├── app/
│ ├── layout.tsx # Root layout, metadata, fonts, theme script
│ ├── page.tsx # Home page (renders ExplorerPage)
│ └── globals.css # Global styles, CSS variables, animations
├── components/
│ ├── charts/ # UsedLanguages, PopularRepos, ForkedRepos
│ ├── form/ # SearchForm, RecentSearches
│ ├── layout/ # Header, Footer
│ ├── pages/ # ExplorerPage (main landing + search)
│ ├── provider/ # Providers (Apollo, Theme, Search, History)
│ ├── ui/ # shadcn/ui: button, card, chart, input, select, skeleton, toast, etc.
│ └── user/ # UserCard, UserProfile, RepoList, StatsContainer, Loading
├── context/
│ ├── SearchContext.tsx # Global search username state
│ ├── SearchHistoryContext.tsx # Recent searches (localStorage)
│ └── ThemeContext.tsx # Light/dark theme (localStorage)
├── hooks/
│ ├── use-toast.ts # Toast notifications
│ └── useSearchHistory.ts # Search history hook
├── app/api/
│ ├── github/graphql/ # GitHub GraphQL proxy
│ └── monitoring/ # Sentry tunnel
├── lib/
│ ├── apollo-client.ts # Apollo → proxy
│ ├── github-graphql-server.ts # Upstream fetch + retries
│ ├── github-api-errors.ts # Error codes/messages
│ ├── report-github-api-error.ts
│ ├── data-utils.ts
│ ├── queries.ts
│ └── utils.ts
├── types/
│ ├── index.ts # User, Repository, UserData
│ └── github-api.ts # Proxy error types
├── public/
│ ├── favicon.ico
│ └── logo.svg
├── .env.example # Environment variable template
├── .env.local # Your secrets (gitignored)
├── package.json
├── tailwind.config.ts
├── next.config.ts
└── README.md| Technology | Purpose |
|---|---|
| Next.js 16 | App Router, SSR, routing, metadata |
| React 19 | UI components, hooks |
| TypeScript 5.6 | Type safety |
| Apollo Client 3.11 | GraphQL client, caching |
| GraphQL 16.9 | Query language |
| Tailwind CSS 3.4 | Utility-first styling |
| shadcn/ui | Accessible UI primitives (Radix) |
| Recharts | Bar charts |
| Framer Motion | Animations |
| Lucide React | Icons |
git clone <repo-url>
cd 21-search-github-users-graphqlnpm installThe app can run without a GitHub token for basic exploration, but the GitHub GraphQL API has strict rate limits for unauthenticated requests (60 requests/hour). For production or heavy use, a token is recommended.
Create .env.local in the project root:
GITHUB_TOKEN=your-github-personal-access-token
NEXT_PUBLIC_SENTRY_DSN=your-sentry-dsnSee Environment Variables for how to create a token.
npm run devThe app will be available at http://localhost:3000.
npm run build
npm startnpm run lint| Variable | Required | Description |
|---|---|---|
GITHUB_TOKEN |
Yes* | GitHub PAT — server-only (/api/github/graphql proxy) |
NEXT_PUBLIC_SENTRY_DSN |
Optional | Sentry client DSN |
SENTRY_ORG / SENTRY_PROJECT / SENTRY_AUTH_TOKEN |
Optional | Source maps at build |
*Without a token the proxy returns a configured error (no public unauthenticated GraphQL from browser).
To create a token:
- GitHub Settings → Personal access tokens
- Classic token with
read:user,public_repo - Add to
.env.localasGITHUB_TOKEN(notNEXT_PUBLIC_*)
GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| Route | Description |
|---|---|
/ |
Home page — hero, search, user profile, charts |
| Route | Method | Purpose |
|---|---|---|
/api/github/graphql |
POST | Proxies GitHub GraphQL (server GITHUB_TOKEN, retries on 502/503/504) |
/api/monitoring |
POST | Sentry tunnel (ad-block bypass) |
Browser → same-origin proxy → https://api.github.com/graphql. Avoids exposing the PAT and fixes intermittent CORS errors when GitHub returns gateway failures.
Main landing page with hero section, streaming animated text, search form, and user profile section.
Reuse: Import and render where you need the full explorer UI.
Controlled input with validation and toast feedback. Submits username to SearchContext.
import { SearchForm } from "@/components/form/SearchForm";
<SearchForm userName={userName} setUserName={setUserName} />;Displays recent usernames as clickable pills. Uses SearchHistoryContext.
import { RecentSearches } from "@/components/form/RecentSearches";
<RecentSearches onSelect={(username) => setUserName(username)} />;Fetches user data via Apollo useQuery, displays profile, stats, repo list, and charts.
import { UserProfile } from "@/components/user/UserProfile";
<UserProfile userName={userName} />;Displays repos with filters (sort, language, type). Shows language and topic badges.
Reuse: Pass repositories and totalCount from your GraphQL response.
Bar charts built with Recharts. Each has a subtitle and label values.
import { UsedLanguages } from "@/components/charts/UsedLanguages";
<UsedLanguages repositories={repositories} />;Light/dark mode toggle. Uses ThemeContext and persists to localStorage.
- User enters a username in SearchForm
- SearchForm validates and calls
setUserNamefrom SearchContext - UserProfile receives
userName, runsuseQuery(GET_USER, { variables: { login: userName } }) - Apollo Client POSTs to
/api/github/graphql(server forwards to GitHub) - Data is cached; loading and error states are handled
- UserProfile renders UserCard, StatsContainer, RepoList, and charts
- Data utils (
lib/data-utils.ts) transform repo data for charts and filters
GraphQL is a query language for APIs. Unlike REST, you specify exactly which fields you need in one request.
Example query used in this project:
query ($login: String!) {
user(login: $login) {
name
avatarUrl
repositories(first: 100) {
totalCount
nodes {
name
stargazerCount
forkCount
}
}
}
}Apollo Client handles:
- ApolloProvider — Wraps the app to provide GraphQL state
- useQuery — Fetches data and handles loading/error
- InMemoryCache — Caches query results
- HttpLink — Sends requests to
/api/github/graphql(same-origin proxy) - Error link — Logs GraphQL and network errors
Usage in this project:
const { data, loading, error } = useQuery<UserData>(GET_USER, {
variables: { login: userName },
});- Next.js — React framework with App Router, SSR, routing
- React — UI library
- TypeScript — Static typing
- @apollo/client — GraphQL client (fetch, cache, hooks)
- graphql — GraphQL parser and utilities
- tailwindcss — Utility-first CSS
- tailwindcss-animate — Animation utilities
- @radix-ui — Accessible primitives (label, select, slot, toast)
- class-variance-authority — Variant styling for components
- clsx + tailwind-merge — Conditional class merging
- lucide-react — UI icons
- react-icons — Additional icons (e.g. MdCopyright)
- recharts — Charts
- framer-motion — Animations
import { cn } from "@/lib/utils";
<div className={cn("base-class", className, isActive && "active-class")} />;- Copy
components/,context/,hooks/,lib/,types/ - Install dependencies:
@apollo/client,graphql,recharts,framer-motion, Radix packages - Wrap your app with
Providers(ThemeProvider, SearchProvider, etc.) - Use
ExplorerPageor individual components as needed
- SearchForm — Needs
SearchContextanduseToast - UserProfile — Needs
ApolloProviderandclient - Charts — Need
repositoriesarray; copylib/data-utils.tshelpers
- GitHub Profile Explorer
- GitHub GraphQL API
- Next.js
- React
- TypeScript
- Apollo Client
- GraphQL
- Tailwind CSS
- shadcn/ui
- Recharts
- Data Visualization
- User Search
- Repository Stats
- Responsive UI
This project is licensed under the MIT License. Feel free to use, modify, and distribute the code as per the terms of the license.
This is an open-source project - feel free to use, enhance, and extend this project further!
If you have any questions or want to share your work, reach out via GitHub or my portfolio at https://www.arnobmahmud.com.
Enjoy building and learning! 🚀
Thank you! 😊


