DEV Community

Cover image for awesome-trending-repos: Modern Web Interface for GitHub Trending
Furkan Köykıran
Furkan Köykıran

Posted on

awesome-trending-repos: Modern Web Interface for GitHub Trending

In my previous blog post, I introduced the awesome-trending-repos project. Back then, the project only wrote data to a README.md file. Things have changed. The project is now a fully functional modern web application.

CI/CD Pipeline
Automated build and deployment process with GitHub Actions


Why a Web Interface?

A README.md file works, but it's static. To track trending projects effectively, I wanted a more interactive experience. Users needed to be able to filter by programming language, search repositories, and see data visualized with charts.

So I built a modern single-page application (SPA) with React + Vite.


Tech Stack

Frontend:

  • React 19 - Latest version
  • Vite - Fast dev server and build tool
  • Tailwind CSS v4 - Utility-first styling
  • Framer Motion - Animations
  • Recharts - Data visualization

Backend/Infrastructure:

  • GitHub Actions - Automation
  • GitHub Pages - Hosting
  • Custom Domain - furkankoykiran.com.tr

Project Structure

The core project structure:

awesome-trending-repos/
├── src/
│   ├── App.jsx          # Main React component
│   ├── main.jsx         # Entry point
│   └── index.css        # Tailwind + custom styles
├── scripts/
│   └── update.js        # Trending data scrape script
├── public/
│   ├── data/
│   │   └── trending.json # Frontend data source
│   └── logo.png
├── .github/workflows/
│   └── update-trends.yml # CI/CD pipeline
└── vite.config.js       # GitHub Pages config
Enter fullscreen mode Exit fullscreen mode

GitHub Pages Integration

When using Vite with GitHub Pages, the most important configuration is the base path. If your project runs in a subdirectory (e.g., github.io/repo-name), you must specify this in vite.config.js:

// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  plugins: [react(), tailwindcss()],
  base: '/awesome-trending-repos/', // GitHub Pages subdirectory
});
Enter fullscreen mode Exit fullscreen mode

Without this setting, asset paths will break in production and you'll get 404 errors.


GitHub Actions Workflow

The workflow runs every day at midnight UTC:

  1. Fetch trending data - Scrape GitHub Trending page
  2. Build frontend - Create dist/ folder with npm run build
  3. Commit data - Commit README and data files if changed
  4. Deploy - Distribute to GitHub Pages
# .github/workflows/update-trends.yml
name: Update and Deploy Trends

on:
  schedule:
    - cron: '0 0 * * *'  # Daily at midnight
  workflow_dispatch:

permissions:
  contents: write
  pages: write
  id-token: write

jobs:
  update-and-build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm ci

      - name: Run update script
        run: npm run update
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Build frontend
        run: npm run build

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: './dist'

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: update-and-build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4
Enter fullscreen mode Exit fullscreen mode

Deployment Flow
Automated deployment flow


Frontend Features

1. Language Filtering

Users can filter by programming language:

const languages = ['All', ...new Set(repos.map(r => r.language).filter(Boolean))];

const filteredRepos = repos.filter(repo => {
  const matchesLang = filter === 'All' || repo.language === filter;
  const matchesSearch = repo.name.toLowerCase().includes(searchQuery.toLowerCase());
  return matchesLang && matchesSearch;
});
Enter fullscreen mode Exit fullscreen mode

2. Search Function

Real-time search across repo name, owner, and description.

3. Visual Statistics

Recharts library for language distribution bar chart and growth leaders list:

<ResponsiveContainer width="100%" height="100%">
  <BarChart data={data?.insights?.topLanguages || []}>
    <CartesianGrid strokeDasharray="8 8" stroke="#ffffff03" />
    <XAxis dataKey="language" stroke="#475569" />
    <YAxis stroke="#475569" />
    <Tooltip contentStyle={{ backgroundColor: 'rgba(15, 23, 42, 0.9)' }} />
    <Bar dataKey="count" radius={[12, 12, 0, 0]}>
      {data?.insights?.topLanguages?.map((entry, index) => (
        <Cell key={index} fill={getLangColor(entry.language)} />
      ))}
    </Bar>
  </BarChart>
</ResponsiveContainer>
Enter fullscreen mode Exit fullscreen mode

4. Deployment Feed

A feed entry is created for each update. Users can see the deployment history.


Custom Domain Setup

To use a custom domain with GitHub Pages:

  1. Create CNAME file - Add your domain to public/CNAME:
   furkankoykiran.com.tr
Enter fullscreen mode Exit fullscreen mode
  1. DNS setting - At your domain provider:
   CNAME furkankoykiran.github.io
Enter fullscreen mode Exit fullscreen mode
  1. HTTPS - GitHub Pages automatically provides SSL with Let's Encrypt.

Performance Tips

1. Asset Optimization

Vite production build automatically does minification and tree-shaking. For large images, consider using optimized images instead of putting everything in public/.

2. Lazy Loading

For large lists, consider virtual scrolling. Not needed for this project with 25 repos, but good to know if you scale.

3. Caching

GitHub Pages automatically adds cache headers. For index.html, use cache-busting:

// vite.config.js
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        entryFileNames: `assets/[name].[hash].js`,
        chunkFileNames: `assets/[name].[hash].js`,
        assetFileNames: `assets/[name].[hash].[ext]`
      }
    }
  }
});
Enter fullscreen mode Exit fullscreen mode

Live Demo

The project is currently live at furkankoykiran.com.tr/awesome-trending-repos. It updates automatically every day.

Project Logo
Project logo

OG Image
Open Graph preview image


Conclusion

Moving from a README.md to a modern web application significantly improved the project's usability. Users now have an interactive experience instead of just a static list.

The GitHub Pages + Vite combination is an excellent solution for static sites. Free, fast, and fully automated with CI/CD.

The project is fully open source. If you want to contribute, send a pull request to the GitHub repo.


Source: blog.furkankoykiran.com.tr

Top comments (0)