Skip to main content

Directory Overview

GitScope follows a standard Vite + React project structure with clear separation between source code, configuration, and build artifacts.
github-dashboard/
├── .github/
│   └── workflows/
│       └── deploy.yml          # GitHub Actions CI/CD
├── public/                     # Static assets (if any)
├── src/                        # Application source code
│   ├── components/             # React components
│   ├── hooks/                  # Custom React hooks
│   ├── App.jsx                 # Root component
│   ├── App.module.css          # Root component styles
│   ├── index.css               # Global styles & CSS variables
│   └── main.jsx                # React entry point
├── dist/                       # Build output (generated)
├── node_modules/               # Dependencies (generated)
├── .gitignore
├── index.html                  # HTML entry point
├── package.json                # Project metadata & dependencies
├── package-lock.json           # Locked dependency versions
├── vite.config.js              # Vite configuration
└── README.md                   # Project documentation

Root Directory

Configuration Files

Purpose: Vite build tool configurationLocation: /vite.config.jsContents:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  base: '/github-dashboard/',
})
Key Settings:
  • plugins: [react()] → Enables React Fast Refresh and JSX transformation
  • base: '/github-dashboard/' → Sets base path for GitHub Pages deployment
Purpose: Project metadata, dependencies, and scriptsLocation: /package.jsonKey Sections:
  • name: github-dashboard
  • type: module (ES modules)
  • homepage: Deployment URL for GitHub Pages
  • scripts: Build, dev, and deployment commands
  • dependencies: Production runtime dependencies
  • devDependencies: Build-time development tools
Purpose: HTML entry point for the applicationLocation: /index.htmlKey Features:
  • Single page application (SPA) entry point
  • Contains root <div id="root"> mount point
  • Imports /src/main.jsx as JavaScript module
  • Vite injects script tags during development and build
Purpose: Excludes files from Git version controlTypical Contents:
  • node_modules/ → Dependencies
  • dist/ → Build output
  • .env → Environment variables
  • Editor-specific files

/src Directory

The src/ folder contains all application source code.

Entry Points

main.jsx

Purpose: React application bootstrapResponsibilities:
  • Imports React and ReactDOM
  • Renders root <App /> component
  • Mounts to #root element in index.html

index.css

Purpose: Global styles and CSS variablesContents:
  • CSS reset (box-sizing, margin, padding)
  • :root CSS variables for light theme
  • [data-theme="dark"] variables for dark theme
  • Global animations (fadeUp, spin, pulse, shimmer)
  • Utility classes (.fade-up, .skeleton, .spinner)
  • Custom scrollbar styles

Root Component

Purpose: Root component and application orchestratorLocation: src/App.jsx + src/App.module.cssResponsibilities:
  • Manages all top-level application state
  • Coordinates data fetching via useGitHub hook
  • Renders child components with appropriate props
  • Handles theme persistence and switching
  • Implements search and pagination logic
Key State Variables:
  • theme, user, repos, selectedRepo, loading, error, page, hasMore, currentUsername, showToken
App.jsx acts as the single source of truth for application state. No global state management library is used.

/src/components Directory

All UI components live here, each with its own .module.css file for scoped styles.

Component Files

Header

Files: Header.jsx, Header.module.cssPurpose: Top navigation barFeatures:
  • App logo and title
  • Dark/light theme toggle button
  • Rate limit indicator (color-coded)
  • “Token API” button to open modal

SearchBar

Files: SearchBar.jsx, SearchBar.module.cssPurpose: User search interfaceFeatures:
  • Text input with Enter key support
  • “Analizar” submit button
  • Suggestion chips (torvalds, gvanrossum, etc.)
  • Loading spinner during search

UserCard

Files: UserCard.jsx, UserCard.module.cssPurpose: User profile displayFeatures:
  • Avatar image
  • Name and bio
  • Company, location, social links
  • Stats grid (repos, followers, following, gists)

LanguageChart

Files: LanguageChart.jsx, LanguageChart.module.cssPurpose: Language distribution visualizationFeatures:
  • Recharts donut chart
  • Fetches languages for top 12 repos
  • In-memory caching with useRef
  • Aggregates bytes by language
  • Legend with color-coded bars

RepoList

Files: RepoList.jsx, RepoList.module.cssPurpose: Repository grid with filtersFeatures:
  • Filter by minimum stars
  • Sort by updated/stars/forks
  • Responsive grid layout
  • Pagination controls
  • Click to select repo for commit view

CommitPanel

Files: CommitPanel.jsx, CommitPanel.module.cssPurpose: Display recent commitsFeatures:
  • Shows last 10 commits for selected repo
  • Commit message, author avatar, SHA
  • Repository metadata sidebar
  • “View on GitHub” link
  • Close button to collapse panel

TokenModal

Files: TokenModal.jsx, TokenModal.module.cssPurpose: GitHub token configurationFeatures:
  • Modal overlay with form
  • Secure password-type input
  • Save and remove token buttons
  • Instructions for creating token

ErrorBanner

Files: ErrorBanner.jsx, ErrorBanner.module.cssPurpose: Dismissible error messagesFeatures:
  • Red banner with error text
  • Close button (X icon)
  • Auto-dismiss option (if implemented)

/src/hooks Directory

Custom React hooks for reusable stateful logic.
Purpose: GitHub API abstraction layerLocation: src/hooks/useGitHub.jsExports:
export function useGitHub() {
  return {
    token,        // Current GitHub token (string)
    saveToken,    // Function to persist/remove token
    rateLimit,    // { remaining, limit, reset }
    getUser,      // Fetch user profile
    getRepos,     // Fetch user repositories
    getCommits,   // Fetch repository commits
    getLanguages, // Fetch repository languages
  }
}
Internal State:
  • token: Loaded from localStorage on mount
  • rateLimit: Extracted from API response headers
Key Methods:
  • request(path, params): Generic API request handler
  • headers(): Generates headers with optional token
  • saveToken(t): Persists token to localStorage
This hook is the only place where fetch is called. All components use this abstraction.

CSS Modules Organization

Why CSS Modules?

GitScope uses CSS Modules for component styling, providing:

Scoped Styles

Class names are automatically namespaced to prevent collisions

Colocation

Each component’s styles live next to its JSX file

Tree Shaking

Unused styles are removed during build

Type Safety

Class names can be autocompleted in modern editors

Naming Convention

Every component follows this pattern:
ComponentName.jsx
ComponentName.module.css
Example:
Header.jsx
Header.module.css

Usage Pattern

import styles from './Header.module.css'

export function Header() {
  return (
    <header className={styles.header}>
      <h1 className={styles.title}>GitScope</h1>
    </header>
  )
}
Generated HTML:
<header class="Header_header__a7b3c">
  <h1 class="Header_title__d8e9f">GitScope</h1>
</header>
The hash suffix (__a7b3c) is generated by Vite to ensure uniqueness.

Global vs. Scoped Styles

Global Styles (index.css)

Used for:
  • CSS variables (colors, spacing, fonts)
  • CSS resets
  • Global utility classes (.fade-up, .skeleton, .spinner)
  • Keyframe animations
  • Theme definitions (:root, [data-theme="dark"])
Example:
:root {
  --bg: #f6f8fa;
  --text: #1a2332;
  --accent: #2563eb;
}

[data-theme="dark"] {
  --bg: #0d1117;
  --text: #e6edf3;
  --accent: #58a6ff;
}

Scoped Styles (.module.css)

Used for:
  • Component-specific layouts
  • Element-specific styles
  • Component state variations (.selected, .active)
Example (RepoList.module.css):
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1rem;
}

.repoCard {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.repoCard.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-soft);
}
Note how .module.css files reference global CSS variables defined in index.css.

Build Output (/dist)

Generated by running npm run build. This folder is deployed to GitHub Pages. Contents:
dist/
├── assets/
│   ├── index-[hash].js       # Bundled JavaScript
│   └── index-[hash].css      # Bundled CSS
├── index.html                # HTML entry with injected assets
└── vite.svg                  # Vite logo (if used)
Characteristics:
  • All JavaScript is bundled and minified
  • CSS Modules are compiled to plain CSS with hashed class names
  • Assets include content hashes for cache busting
  • Source maps generated for debugging (if configured)
Never manually edit files in /dist. They are regenerated on every build.

GitHub Actions Workflow

Location: .github/workflows/deploy.yml Purpose: Automated deployment to GitHub Pages on push to main branch Typical Steps:
  1. Checkout code
  2. Install Node.js
  3. Install dependencies (npm ci)
  4. Build application (npm run build)
  5. Deploy dist/ folder to gh-pages branch
The gh-pages package in devDependencies is used by the deploy script to push the build to the gh-pages branch.

File Naming Conventions

File TypeConventionExample
ComponentsPascalCase + .jsxSearchBar.jsx
Component StylesPascalCase + .module.cssSearchBar.module.css
HookscamelCase + .jsuseGitHub.js
Global Styleslowercase + .cssindex.css
Configlowercase + .jsvite.config.js

Import Path Patterns

Relative Imports

All imports use relative paths (no path aliases configured). Examples:
// In App.jsx
import { useGitHub } from './hooks/useGitHub'
import { Header } from './components/Header'
import styles from './App.module.css'

// In RepoList.jsx
import styles from './RepoList.module.css'
import { Star, GitFork } from 'lucide-react'

Import Order Convention

// 1. External dependencies
import { useState, useEffect } from 'react'
import { Star, GitFork } from 'lucide-react'

// 2. Internal hooks
import { useGitHub } from './hooks/useGitHub'

// 3. Internal components
import { Header } from './components/Header'

// 4. Styles
import styles from './App.module.css'

Adding New Components

To add a new component, follow these steps:
1

Create Component File

Create src/components/NewComponent.jsx
import styles from './NewComponent.module.css'

export function NewComponent({ prop1, prop2 }) {
  return (
    <div className={styles.container}>
      {/* Component JSX */}
    </div>
  )
}
2

Create Styles File

Create src/components/NewComponent.module.css
.container {
  background: var(--bg-card);
  padding: 1rem;
  border-radius: var(--radius);
}
3

Import in Parent

Import and use in parent component (usually App.jsx)
import { NewComponent } from './components/NewComponent'

// In render:
<NewComponent prop1={value1} prop2={value2} />

Next Steps

Architecture

Learn about system architecture and design patterns

Tech Stack

Explore the technologies and dependencies

Build docs developers (and LLMs) love