Skip to content

parwan-as/github-explorer

Repository files navigation

GitHub Stars Explorer

A modern React SPA for exploring, searching, bookmarking, and comparing GitHub repositories. Built with React 19, TypeScript, Vite, Tailwind CSS 4, and shadcn/ui.

Features

  • Repository Search — Search GitHub repos with filters for language, star count, sort order, and creation date. Debounced input with keyboard shortcut (/ to focus).
  • Repository Details — View full repo info including stats, topics, dates, and an estimated star history chart.
  • Bookmarks — Save repos to a persistent bookmark list (localStorage). Filter, sort, and export as JSON.
  • Compare — Select up to 4 repos and compare them side-by-side with metrics and overlaid star history charts.
  • Authentication — Sign in with a GitHub Personal Access Token to increase the API rate limit from 60 to 5,000 requests/hour.
  • Dark/Light Theme — Toggle between themes with OS preference detection and localStorage persistence.

Getting Started

Prerequisites

  • Node.js 18 or later
  • npm (comes with Node.js)

No API keys, environment variables, or external services are required. The app uses the public GitHub API out of the box.

1. Clone and install

git clone <repo-url>
cd github-explorer
npm install

2. Start the dev server

npm run dev

Open http://localhost:5173 in your browser. Vite provides hot module replacement, so changes to source files reflect instantly without a full page reload.

3. (Optional) Authenticate for higher rate limits

The app works immediately without authentication, but the public GitHub API is limited to 60 requests per hour. To get 5,000 requests per hour:

  1. Go to GitHub Settings > Tokens and generate a classic Personal Access Token (no scopes needed).
  2. Click Sign in in the app header and paste the token.

The token is stored in your browser's localStorage and never sent anywhere except the GitHub API. Rate limit status is shown in the header when authenticated.

Available Scripts

Script Command Description
npm run dev vite Start dev server with HMR at localhost:5173
npm run build tsc -b && vite build Type-check and build for production into dist/
npm run preview vite preview Serve the production build locally
npm run lint eslint . Check for lint issues
npm run lint:fix eslint . --fix Auto-fix lint issues
npm run type-check tsc --noEmit Type-check without emitting files

Production Build

npm run build
npm run preview

The first command type-checks and bundles everything into dist/. The second serves it locally at http://localhost:4173 so you can verify the build before deploying. The output is a static site — deploy dist/ to any static hosting provider (Vercel, Netlify, GitHub Pages, etc.).

Project Structure

src/
├── main.tsx                        # Entry point
├── App.tsx                         # Root component (routing, providers)
├── index.css                       # Global styles & CSS variables
│
├── pages/
│   ├── SearchPage.tsx              # Search interface with filters
│   ├── RepoDetailPage.tsx          # Single repo view with star chart
│   ├── BookmarksPage.tsx           # Saved repos list
│   ├── ComparePage.tsx             # Side-by-side comparison
│   └── NotFoundPage.tsx            # 404
│
├── components/
│   ├── layout/
│   │   ├── Layout.tsx              # App shell (header + footer)
│   │   └── Header.tsx              # Navigation, auth, theme toggle
│   ├── repo/
│   │   └── RepoCard.tsx            # Repo card for search results
│   ├── compare/
│   │   └── CompareBar.tsx          # Floating bar for selected repos
│   ├── charts/
│   │   └── StarHistoryChart.tsx    # Star growth area chart
│   └── ui/                         # shadcn/ui primitives
│
├── hooks/
│   ├── useSearch.ts                # React Query hook for search
│   └── useTheme.tsx                # Theme context provider
│
├── store/
│   ├── authStore.ts                # Auth state (token, user, rate limit)
│   ├── bookmarkStore.ts            # Bookmarks (persisted to localStorage)
│   └── compareStore.ts             # Compare queue (max 4 repos)
│
├── lib/
│   ├── api.ts                      # GitHub search API + language data
│   ├── github.ts                   # GitHubClient (auth, fetch, rate limits)
│   ├── starHistory.ts              # Star history fetcher (sampled pages)
│   └── utils.ts                    # cn() utility
│
└── types/
    └── github.ts                   # TypeScript interfaces

Architecture

Routing

React Router v7 with lazy-loaded pages via React.lazy() + Suspense:

Route Page Description
/ SearchPage Search and filter repositories
/repo/:owner/:name RepoDetailPage Repository details and star history
/bookmarks BookmarksPage Saved repositories
/compare ComparePage Side-by-side comparison
* NotFoundPage 404 fallback

State Management

Three layers of state:

Layer Tool Purpose
Global Zustand Auth, bookmarks, compare queue
Server React Query API data with caching (5-min stale time)
Local React hooks UI state (filters, dialogs, inputs)

Bookmarks are persisted to localStorage via Zustand's persist middleware.

GitHub API Integration

The app uses the GitHub REST API (api.github.com):

  • GET /search/repositories — Search with query filters
  • GET /repos/{owner}/{repo} — Fetch repo details
  • GET /repos/{owner}/{repo}/stargazers — Sampled pagination for star history estimation
  • GET /user — Validate token and fetch user profile

Rate limit headers are parsed from every response and surfaced in the UI. On 401, the token is auto-cleared. On 403 (rate limit exceeded), a user-friendly error with reset time is shown.

Star History

GitHub doesn't expose historical star counts directly. The app estimates star growth by sampling ~8 pages from the stargazers endpoint using logarithmic distribution and interpolating the timeline.

Tech Stack

Category Technology
Framework React 19
Language TypeScript 5.9
Build Vite 8
Styling Tailwind CSS 4
Components shadcn/ui (Radix UI)
State Zustand
Server State TanStack React Query
Routing React Router v7
Charts Recharts
Icons Lucide React
Theming next-themes
Notifications Sonner
Dates date-fns

Design System

  • Fonts: Fira Code (headings/mono) + Fira Sans (body)
  • Colors: Blue primary (#2563EB), orange accent (#F97316), slate neutrals
  • Dark mode: Default, OLED-optimized with full CSS variable system
  • Responsive: Mobile-first with 1/2/3 column grid breakpoints
  • Accessibility: WCAG contrast ratios, keyboard navigation, focus rings, semantic HTML

Full design system specs are in design-system/github-stars-explorer/MASTER.md.

License

Private project.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages