ADR-002: GitHub Projects Showcase
| Status | Accepted (Amended) |
|---|---|
| Date | 2026-01-01 |
| Amended | 2026-01-23 |
| Decision Makers | Christopher Joseph |
| Technical Story | Communicate GitHub project portfolio to engineers and recruiters |
| Depends On | ADR-001 (Enable Docs Plugin) |
| Review Process | LLM Council multi-model review (2026-01-23) |
Summary for All Readers
This proposal creates a curated portfolio page at /projects showing selected GitHub projects with live statistics (stars, recent activity). Projects are hand-picked and organized by category rather than showing everything automatically. The page loads quickly because data is collected when the site is published, not when visitors view it.
For recruiters: See demonstrated skills, project impact, and technical depth at a glance. For engineers: Discover projects, view live stats, and find related blog posts and documentation.
Context and Problem Statement
As an engineer, communicating the breadth and depth of GitHub projects is valuable for:
- Recruiters: Understanding technical capabilities and active contributions
- Engineers: Discovering interesting projects, potential collaboration opportunities
- Personal branding: Demonstrating continuous learning and open source involvement
Currently, the only GitHub visibility is a navbar link to the organization. There's no curated view of projects, their status, or their significance.
Decision Drivers
- Curation over automation: Highlight meaningful projects, not just everything
- Fresh data: Show current stars, activity, and status without manual updates
- Context: Explain why projects matter, not just metadata
- Performance: Data fetched at build time, no slow API calls when visitors browse
- Resilience: Site builds should never fail due to GitHub API issues
- Maintainability: Simple configuration, minimal ongoing effort
- Audience awareness: Different needs for recruiters vs. technical visitors
Considered Options
Option 1: Hybrid Projects Page with Build-time Data Script (Recommended)
Create a /projects page that:
- Curates which projects to display via a
projects.jsonconfig file - Fetches live metadata (stars, language, last updated) from GitHub API at build time using a simple Node.js script
- Allows adding descriptions, categories, impact statements, and skills demonstrated
- Groups projects by skill area and status
Implementation approach:
- Prebuild script (
scripts/fetch-projects.js) runs before Docusaurus build - Script reads
projects.json, fetches GitHub data, writessrc/data/projects.generated.json - React page component at
/src/pages/projects.tsximports the generated data - Graceful fallback to cached data if API fails
Pros:
- Full curation control over which projects appear and how they're presented
- Simpler than a Docusaurus plugin (easier to debug and maintain)
- Live metadata without runtime API calls
- Rich context for each project
- Fast page loads (static HTML)
- Builds succeed even if GitHub is down
Cons:
- Requires build to update stats (deploy triggers fresh data)
- Need to commit cached data for fallback
Option 2: Custom Docusaurus Plugin
Hook into Docusaurus lifecycle methods (loadContent) for data fetching.
Pros:
- Integrated with Docusaurus build pipeline
- Access to plugin lifecycle hooks
Cons:
- More complex to implement and debug
- Tied to Docusaurus internals
- Overkill for this use case
Option 3: GitHub Profile Widget (Embed)
Use GitHub's profile README or third-party widgets to embed project data.
Pros: Zero development effort, always up-to-date Cons: No curation control, inconsistent styling, external dependency
Option 4: Static Markdown Projects Page
Manually maintain a Markdown page listing projects.
Pros: Simple, no API needed Cons: Data goes stale quickly, manual maintenance burden
Decision Outcome
Chosen option: Option 1 - Hybrid Projects Page with Build-time Data Script
This balances curation (what recruiters and engineers want to see) with freshness (live stats that build credibility), while keeping implementation simple and resilient.
Data Model
Configuration File (projects.json)
{
"$schema": "./projects.schema.json",
"projects": [
{
"repo": "amiable-dev/stentorosaur",
"category": "active",
"featured": true,
"skills": ["TypeScript", "Plugin Development", "GitHub API"],
"title": "Stentorosaur",
"description": "GitHub-issue-based status monitoring plugin for Docusaurus",
"impact": "Powers real-time status pages with zero infrastructure",
"role": "Creator & Maintainer",
"highlights": [
"Published to npm with 500+ weekly downloads",
"Powers the /status page on this site"
],
"tags": ["docusaurus", "monitoring", "open-source"],
"relatedPosts": ["/stentorosaur-release"],
"relatedDocs": ["/docs/adrs/ADR-002-github-projects-showcase"]
}
]
}
Enriched at Build Time
The script adds from GitHub API:
stars: Star countlanguage: Primary languagelastUpdated: Last push dateopenIssues: Open issue countlicense: License namefetchedAt: Timestamp for cache freshness display
Categories
| Category | Display Label | Description |
|---|---|---|
active | Active | Currently in development |
maintained | Maintained | Stable, accepting contributions |
historical | Historical | No longer maintained, preserved for reference |
Implementation Plan
Phase 1: Build Script
Create scripts/fetch-projects.js:
// Pseudocode
1. Read projects.json
2. For each project:
- Fetch GitHub API (with GITHUB_TOKEN from env)
- Merge curated data with API response
3. Write to src/data/projects.generated.json
4. On API failure:
- Log warning (don't fail build)
- Use existing cached file if available
- Mark project with `dataStale: true`
Add to package.json:
{
"scripts": {
"prebuild": "node scripts/fetch-projects.js",
"build": "docusaurus build"
}
}
Phase 2: Projects Page Component
Create /src/pages/projects.tsx:
- Hero section: "What I Build" with portfolio summary
- Featured projects section (1-2 expanded cards)
- Skill-based groupings (alternative to just Active/Historical)
- Project cards showing:
- Title and curated description
- Impact statement (recruiter-friendly)
- Stars, language, last activity badges
- Skills/tech stack tags
- Links to repo, blog posts, docs
- Filter by category and skill
- "Last synced" timestamp for transparency
Phase 3: Integration
- Create
projects.jsonwith initial curation - Add Projects link to navbar
- Cross-link from relevant blog posts
- Commit initial
projects.generated.jsonfor fallback
Phase 4: Styling
- Match site theme (pink-red light, cyan-blue dark)
- Responsive design for mobile
- Accessible cards (ARIA labels, keyboard navigation)
- Hover states and visual hierarchy
Error Handling and Resilience
Key principle: The build should never fail due to GitHub API issues.
Security Considerations
| Concern | Mitigation |
|---|---|
| Token in CI/CD | Use GitHub Actions secrets or hosting provider env vars |
| Token in client bundle | Script runs at build time only; token never shipped to browser |
| Rate limits | Authenticated requests get 5,000/hour; batch requests; cache aggressively |
| Private repos | Excluded by default; only public repos in projects.json |
UI Design
┌─────────────────────────────────────────────────────────────┐
│ What I Build │
│ Open source projects and technical explorations │
│ Last synced: Jan 1, 2026 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─ FEATURED ───────────────────────────────────────────┐ │
│ │ Stentorosaur ⭐ 42 │ │
│ │ GitHub-issue-based status monitoring for Docusaurus │ │
│ │ │ │
│ │ IMPACT: Powers real-time status pages with zero │ │
│ │ infrastructure costs │ │
│ │ │ │
│ │ Skills: TypeScript, Plugin Dev, GitHub API │ │
│ │ Role: Creator & Maintainer │ │
│ │ │ │
│ │ [View Repo] [Read Blog Post] [See Architecture] │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ ─── By Skill ─────────────────────────────────────────── │
│ [All] [TypeScript] [Python] [DevOps] [Frontend] │
│ │
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
│ │ amiable-docusaurus │ │ cli-tool-example │ │
│ │ This website │ │ Python CLI framework │ │
│ │ ⭐ 12 TypeScript │ │ ⭐ 89 Python │ │
│ │ [ACTIVE] │ │ [MAINTAINED] │ │
│ └─────────────────────────┘ └─────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Consequences
Positive
- Curated portfolio presentation tailored for recruiters
- Live stats build credibility (not manually inflated)
- Skill-based grouping shows breadth of capabilities
- Cross-linking with blog and docs content
- Resilient builds that succeed regardless of GitHub availability
- Simple implementation (prebuild script vs. complex plugin)
Negative
- Build-time data means stats update only on deploy
- Need to update
projects.jsonwhen adding new projects - Cached data may be stale (mitigated by showing sync timestamp)
Risks
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| GitHub API down during build | Low | None | Graceful fallback to cached data |
| Rate limits exceeded | Low | Low | Use token (5k/hr); limit to ~20 projects |
| Stale curated descriptions | Medium | Medium | Quarterly review; compare to GitHub descriptions in CI |
| Token exposure | Low | High | Build-time only; never in client bundle; use secrets |
| Abandoned projects hurt perception | Medium | Low | Use "Historical" label; limit display to meaningful work |
Success Metrics
- Projects page becomes top-5 visited page within 6 months
- Recruiters mention portfolio or projects in interviews
- Engineers engage with project links (GitHub referrals from site)
- Build success rate remains >99% (API issues don't cause failures)
UI/UX Improvements (2026-01 Review)
Current State Assessment
The initial implementation delivers curated GitHub projects with live statistics, organized by category (Featured, Active, Maintained), skill-based filtering, project cards with stars/language/descriptions, and links to ADRs/docs/GitHub.
Identified Issues
| Area | Issue | Impact |
|---|---|---|
| Navigation | No in-page navigation for jumping between sections | Users must scroll to find categories |
| Navigation | Overwhelming filter tags without hierarchy | Cognitive overload, decision paralysis |
| Navigation | No search functionality | Engineers can't quickly find specific projects |
| Data Representation | Star counts lack context | Raw numbers don't convey significance |
| Data Representation | Status badges are passive/static | Missing urgency and visual differentiation |
| Data Representation | ADR/Post counts buried in cards | Cross-content value not immediately visible |
| Visual Hierarchy | All cards have same visual weight | Featured projects don't stand out |
| Visual Hierarchy | No differentiation by project type | Monolithic appearance |
| Interaction | No sorting capability | Users can't prioritize by stars/activity/name |
| Interaction | Static filtering only | Limited exploration paths |
| Information Architecture | Repetitive role information | "Creator & Maintainer" adds noise |
| Information Architecture | Missing activity recency | No sense of project freshness |
Validated Improvements (LLM Council Review)
The following improvements were validated by multi-model review for serving both recruiters and engineers:
High-Value for Both Audiences
| Improvement | Recruiter Value | Engineer Value | Complexity |
|---|---|---|---|
| Search Input | Quickly find projects by name/tech | Find specific repos, filter by skill | Low |
| Sticky Section Navigation | Efficient scanning of portfolio | Jump to categories of interest | Low |
| "Last Updated" & Activity Recency | See active maintenance | Identify living projects | Low |
| Color-coded Status Badges | Visual project health | Quick active/archived scanning | Low |
Recruiter-Focused Improvements
| Improvement | Value | Complexity |
|---|---|---|
| Surface ADR/Post counts as pills | Shows technical depth | Low |
| Star context (percentile badges) | Understand relative success | Medium |
| Featured card differentiation | Highlight best work | Medium |
Engineer-Focused Improvements
| Improvement | Value | Complexity |
|---|---|---|
| Sort dropdown (stars/activity/name) | Prioritize exploration | Medium |
| Dual CTAs (Repo vs Demo/Docs) | Direct paths to value | Low |
Complexity vs Value Analysis
Recommended Approach:
- Sort Dropdown instead of sortable columns (cards don't naturally support column sorting)
- Defer collapsible filter sidebar until tag taxonomy is simplified
- Remove repetitive role info via legend/global statement
Avoid Over-Engineering:
- Don't add table/list view toggle (premature)
- Don't implement infinite scroll (not enough projects)
- Don't add comparison features (niche use case)
Implementation Phases
Phase 0: Information Architecture Cleanup
Clean up foundations before adding features:
- Consolidate role info: Add global "Creator & Maintainer of all projects" statement in hero
- Simplify tag taxonomy: Group skills into categories (Languages, Frameworks, Domains)
- Define "Featured" criteria: Document in config what qualifies (>50 stars, active development, public impact)
- Remove redundant fields: Audit cards for repeated/low-value information
Phase 1: Quick Wins (Low Complexity, High Impact)
Visual improvements with minimal code changes:
-
Color-coded status badges:
- Active: Green (#22c55e)
- Maintained: Blue (#3b82f6)
- Historical: Gray (#6b7280)
-
Surface ADR/Post counts as pills:
- "3 ADRs" pill links to filtered ADR list
- "7 Posts" pill links to project tag page
-
Add "Last updated" to cards:
- Show relative time ("2 days ago", "3 months ago")
- Color-code by recency (green < 1 month, yellow < 6 months, gray > 6 months)
-
Star context badges:
- Add tier badges: "Popular" (>100 stars), "Rising" (>25 stars)
Phase 2: Navigation & Discovery (Medium Complexity)
Improve findability and exploration:
-
Search input:
- Instant filter by project name, description, skills
- Debounced input with clear button
- Empty state with suggestions
-
Sticky section navigation:
- Anchor links for Featured, Active, Maintained, Historical
- Highlight current section on scroll
- Mobile: horizontal scrollable tabs
-
Sort dropdown:
- Options: "Most Stars", "Recently Updated", "Name A-Z"
- Persist preference in localStorage
-
Empty states:
- When filters/search return nothing
- Helpful message with reset action
Phase 3: Visual Hierarchy (Higher Complexity)
Differentiate content importance:
-
Featured card expansion:
- Larger card size (2x width on desktop)
- Show impact statement and highlights inline
- Hero image support
-
Category visual separation:
- Section headers with project counts
- Subtle background color per category
- Collapsible sections (expand/collapse by default based on count)
Updated UI Mockup
┌─────────────────────────────────────────────────────────────┐
│ What I Build │
│ Creator & maintainer of open source tools │
│ Last synced: Jan 1, 2026 │
│ │
│ [🔍 Search projects...] Sort: [Most Stars ▼] │
├─────────────────────────────────────────────────────────────┤
│ Featured · Active · Maintained · Historical ← sticky │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─ FEATURED (expanded 2x card) ─────────────────────────┐ │
│ │ Stentorosaur ⭐ 42 Popular │ │
│ │ GitHub-issue-based status monitoring for Docusaurus │ │
│ │ │ │
│ │ IMPACT: Powers real-time status pages with zero │ │
│ │ infrastructure costs │ │
│ │ │ │
│ │ [ACTIVE 🟢] Updated 2 days ago │ │
│ │ │ │
│ │ [3 ADRs] [7 Posts] TypeScript · Docusaurus · GitHub │ │
│ │ │ │
│ │ [View Repo] [Live Demo] [Documentation] │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
│ ─── Active (4 projects) ──────────────────────────────── │
│ │
│ ┌──────────────────────┐ ┌──────────────────────────┐ │
│ │ amiable-docusaurus │ │ arbiter-bot │ │
│ │ This website │ │ Automated trading bot │ │
│ │ ⭐ 12 TypeScript │ │ ⭐ 89 Rising Python │ │
│ │ [ACTIVE 🟢] 5d ago │ │ [ACTIVE 🟢] 1d ago │ │
│ │ [2 ADRs] [19 Posts] │ │ [0 ADRs] [8 Posts] │ │
│ │ [Repo] [Docs] │ │ [Repo] │ │
│ └──────────────────────┘ └──────────────────────────┘ │
│ │
│ ─── Maintained (3 projects) ───────────────────────────── │
│ ... │
└─────────────────────────────────────────────────────────────┘
Accessibility Considerations
| Requirement | Implementation |
|---|---|
| Keyboard navigation | Tab through cards, Enter to expand/follow links |
| Screen readers | ARIA labels for badges, live regions for filter results |
| Color contrast | Status colors meet WCAG AA (4.5:1 ratio) |
| Focus indicators | Visible focus rings on all interactive elements |
| Motion preferences | Respect prefers-reduced-motion for transitions |
Success Metrics (Updated)
| Metric | Target | Measurement |
|---|---|---|
| Time to find project | < 10 seconds | User testing |
| Search usage rate | > 30% of visitors | Analytics |
| Filter engagement | > 50% interact with filters | Analytics |
| Cross-content clicks | > 20% click ADR/Post links | Analytics |
| Accessibility score | 100 on Lighthouse | Automated |
Future Enhancements
- Project detail pages: Auto-generate
/projects/{slug}from README - Contribution graphs: Show commit activity heatmaps
- Skills matrix: Aggregate technologies across all projects
- Automated curation suggestions: GitHub Action that suggests new projects to add
- Comparison view: Side-by-side project comparison (deferred from Phase 3)
- Table/List view toggle: Alternative compact view for power users
Related Decisions
- ADR-001: Enable Docs Plugin (enables cross-linking to project documentation)