
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
portfolio-github-integration
Advanced tools
Browser-native library to fetch GitHub repositories and custom metadata for dynamic portfolio rendering
A browser-native TypeScript library that automatically fetches and aggregates portfolio metadata from GitHub repositories containing configuration files. Perfect for dynamic portfolio websites built with React, Vue, Angular, or vanilla JavaScript.
This library scans a GitHub user's repositories for repo.config.json files in the src/ directory and returns a comprehensive array of portfolio metadata for published projects.
npm install portfolio-github-integration
import { getRepos } from 'portfolio-github-integration';
// Simple usage (public repositories only)
const portfolioData = await getRepos('your-github-username');
// With authentication token (backward compatible)
const portfolioData = await getRepos('your-github-username', 'ghp_your_token_here');
console.log(portfolioData);
import { getRepos } from 'portfolio-github-integration';
// Performance-optimized configuration
const portfolioData = await getRepos('your-github-username', {
token: 'ghp_your_token_here', // GitHub Personal Access Token
maxRepos: 50, // Limit repositories to scan (default: 100)
parallel: true, // Enable parallel processing (default: true)
cacheMs: 20 * 60 * 1000, // Cache results for 20 minutes (default: 20 min)
debug: true, // Enable debug console logging (default: false)
onProgress: (processed, total, repoName) => {
console.log(`Progress: ${processed}/${total} - Scanning ${repoName}`);
// Update your UI progress bar here
}
});
console.log(`Found ${portfolioData.length} published repositories`);
import React, { useState, useEffect } from 'react';
import { getRepos } from 'portfolio-github-integration';
function Portfolio() {
const [repos, setRepos] = useState([]);
const [loading, setLoading] = useState(true);
const [progress, setProgress] = useState({ current: 0, total: 0 });
useEffect(() => {
async function fetchPortfolio() {
try {
const data = await getRepos('your-username', {
token: process.env.REACT_APP_GITHUB_TOKEN,
maxRepos: 30,
debug: false, // Disable debug logs in production
onProgress: (current, total, repoName) => {
setProgress({ current, total });
}
});
setRepos(data);
} catch (error) {
console.error('Failed to fetch portfolio:', error);
} finally {
setLoading(false);
}
}
fetchPortfolio();
}, []);
if (loading) {
return (
<div>
Loading portfolio... {progress.current}/{progress.total}
</div>
);
}
return (
<div>
{repos.map(repo => (
<div key={repo.name}>
<h3>{repo.title}</h3>
<p>{repo.info}</p>
{repo.thumbnail && <img src={repo.thumbnail} alt={repo.title} />}
</div>
))}
</div>
);
}
repo.config.json file to the src/ directory of repositories you want to include in your portfoliopublished: true in their configCreate a src/repo.config.json file in each repository you want to include:
{
"published": true,
"title": "My Awesome Project",
"info": "A brief description of what this project does",
"publicUrl": "https://your-project-url.com",
"thumbnail": "assets/screenshot.png",
"branch": "main",
"customConfig": {
"tags": ["react", "typescript"],
"featured": true,
"difficulty": "intermediate"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
published | boolean | ✅ | Whether to include this repo in portfolio results |
title | string | ❌ | Display title for the project |
info | string | ❌ | Project description |
publicUrl | string | ❌ | Public URL of the deployed project (e.g., Vercel/Netlify) |
thumbnail | string | ❌ | Path to thumbnail image (relative to repo root) |
branch | string | ❌ | Branch to use for thumbnail URL (defaults to "main") |
customConfig | object | ❌ | Custom configuration object for additional metadata |
The library returns an array of RepoMetadata objects:
interface RepoMetadata {
name: string; // Repository name
url: string; // GitHub repository URL
publicUrl?: string; // Public URL of the project
thumbnail?: string; // Full URL to thumbnail image (optional)
info: string; // Project description
title: string; // Project title
customConfig?: Object; // Optional custom configuration object
}
[
{
name: "my-portfolio-site",
url: "https://github.com/username/my-portfolio-site",
publicUrl: "https://your-project-url.com",
thumbnail: "https://raw.githubusercontent.com/username/my-portfolio-site/main/assets/screenshot.png",
info: "A responsive portfolio website built with React",
title: "Portfolio Website",
customConfig: {
tags: ["react", "typescript"],
featured: true,
difficulty: "intermediate"
}
},
{
name: "data-visualization-tool",
url: "https://github.com/username/data-visualization-tool",
publicUrl: "https://your-project-url.com",
thumbnail: "https://raw.githubusercontent.com/username/data-visualization-tool/main/assets/preview.png",
info: "Interactive charts and graphs for data analysis",
title: "Data Viz Tool",
customConfig: {
tags: ["d3", "javascript"],
featured: false,
difficulty: "advanced"
}
}
]
getRepos(username, options?)| Parameter | Type | Description |
|---|---|---|
username | string | GitHub username (required) |
options | string | GetReposOptions | Token string (backward compatible) or options object |
interface GetReposOptions {
token?: string; // GitHub Personal Access Token
maxRepos?: number; // Max repositories to scan (default: 100)
parallel?: boolean; // Enable parallel processing (default: true)
cacheMs?: number; // Cache duration in ms (default: 1200000 = 20 min)
debug?: boolean; // Enable debug console logging (default: false)
onProgress?: (processed: number, total: number, repoName: string) => void;
}
Promise<RepoMetadata[]>
interface RepoMetadata {
name: string; // Repository name
url: string; // GitHub repository URL
publicUrl?: string; // Public URL of the project
thumbnail?: string; // Full URL to thumbnail image (optional)
info: string; // Project description
title: string; // Project title
customConfig?: any; // Custom configuration object
}
For private repositories and higher rate limits, you'll need a GitHub Personal Access Token:
public_repo (for public repositories)repo (for private repositories)// Environment variable (recommended)
const repos = await getRepos('username', {
token: process.env.GITHUB_TOKEN
});
// Direct usage (not recommended for production)
const repos = await getRepos('username', {
token: 'ghp_your_token_here'
});
| Authentication | Requests per Hour |
|---|---|
| No token | 60 requests |
| With token | 5,000 requests |
Enable debug mode to see detailed console logging during repository scanning:
const repos = await getRepos('username', {
debug: true // Enable console logging (default: false)
});
Debug output includes:
Production recommendation: Keep debug: false (default) in production environments to avoid console pollution.
The library gracefully handles:
The library includes comprehensive Jest tests covering:
# Run tests (uses 'octocat' as default test user)
npm test
# Run tests with your own GitHub username
TEST_GITHUB_USERNAME=yourusername npm test
# Or use the custom test script
npm run test:custom --user=yourusername
# Run tests in watch mode
npm run test:watch
# Build the library
npm run build
# Development mode (watch TypeScript compilation)
npm run dev
This library is built as a browser-first ES Module and includes:
This library is built for maximum performance with enterprise-grade optimizations:
| Scenario | Before Optimization | After Optimization | Improvement |
|---|---|---|---|
| 50 repositories | ~15-30 seconds | ~3-5 seconds | 5-6x faster |
| 100 repositories | ~30-60 seconds | ~5-8 seconds | 6-8x faster |
| Cached results | N/A | ~50ms | Instant |
| With authentication | Same as above | Same + private repos | Enhanced access |
We provide comprehensive example applications demonstrating all library features:
All examples include:
All example applications are available in the GitHub repository. Each example includes detailed setup and running instructions in its respective README file:
Visit the GitHub repository to explore the complete example implementations.
This library is open source and available on GitHub: https://github.com/MatheusFonseca849/github-portfolio-integration
If you encounter any bugs, issues, or have feature requests, please submit them on our GitHub repository:
MIT © Matheus Fonseca
FAQs
Browser-native library to fetch GitHub repositories and custom metadata for dynamic portfolio rendering
We found that portfolio-github-integration demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.