Display live GitHub repository cards on any website — no build tools, no framework, no manual updates. One script tag and one function call.
Developers and organizations frequently want to showcase their GitHub repositories on portfolios, documentation, or marketing pages. The usual approaches all have painful trade-offs:
Manual HTML
Copy-pasted repo details go stale the moment you push a new commit or earn another star.
Custom API code
Re-implementing GitHub API integration, caching, and card rendering from scratch for every project.
Heavy frameworks
Pulling in a full component library just to display repository metadata is significant overhead.
RepoWidget eliminates all three. Drop in the script, call one function — repositories appear live, always current, with zero maintenance.
<!-- Before: static, stale, hand-maintained -->
<div class="repo-card">
<h3>my-cool-project</h3>
<p>A tool I made — ★ 42 forks 7</p> <!-- already wrong -->
</div>
<!-- After: live data, always correct -->
<div id="repos"></div>
<script src="https://cdn.jsdelivr.net/npm/repowidget/dist/repoWidget.min.js"></script>
<script>
createRepoWidget({ username: 'your-username', containerId: 'repos' });
</script>
Fetches directly from the GitHub API — stars, forks, descriptions, and language badges are always current. No manual updates needed.
24-hour localStorage cache with ETag support prevents redundant API calls and keeps you well within GitHub's 60 req/hr rate limit.
Override card styles, text colors, grid columns, sort order, filter criteria, and hover animations to match any design system.
Mobile-first CSS Grid with configurable column counts per breakpoint. Cards adapt consistently across phone, tablet, and desktop.
RepoWidget is a thin layer over the GitHub REST API v3. On each page load it checks localStorage for
a valid cache; on a miss (or after 24 hours) it fires a conditional request with an ETag header so
unchanged data costs zero bytes. The resulting JSON is filtered, sorted, and rendered in a single
innerHTML write.
Fetch request is sent
to api.github.com/users/{'{'}username{'}'}/repos, optionally with a stored ETag
to receive a 304 instead of redundant data.
stars,
forks, name, size, or updated and
capped at maxRepos.
Pass an options object to createRepoWidget(). Only
username and containerId are required.
| Option | Type | Default | Description |
|---|---|---|---|
username |
string | — | GitHub username or organization name |
containerId |
string | — | ID of the element to render cards into |
maxRepos |
number | 6 |
Maximum number of repositories to display |
sortBy |
string | 'stars' |
stars, forks, name, size, or
updated
|
forked |
boolean | false |
Include forked repositories |
exclude |
string[] | [] |
Repository slugs to hide |
| Option | Type | Default | Description |
|---|---|---|---|
columns.mobile |
number | 1 |
Grid columns on small screens |
columns.tablet |
number | 2 |
Grid columns on medium screens |
columns.desktop |
number | 3 |
Grid columns on large screens |
| Option | Description |
|---|---|
cardStyles |
Object of CSS properties applied to each card element |
textStyles.titleColor |
CSS color for the repository name |
textStyles.descriptionColor |
CSS color for the description text |
| Option | Signature | Description |
|---|---|---|
onLoad |
(repos) => void |
Called after cards are rendered; receives the array of displayed repos |
onError |
(err) => void |
Called when the API request or rendering fails |
<div id="repos"></div>
<script src="https://cdn.jsdelivr.net/npm/repowidget/dist/repoWidget.min.js"></script>
<script>
createRepoWidget({
username: 'your-username',
containerId: 'repos',
maxRepos: 6,
sortBy: 'stars',
exclude: ['your-username.github.io'],
columns: { mobile: 1, tablet: 2, desktop: 3 }
});
</script>
import { useEffect } from 'react';
import { createRepoWidget } from 'repowidget';
function RepoDisplay() {
useEffect(() => {
createRepoWidget({ username: 'your-username', containerId: 'repos', maxRepos: 6 });
}, []);
return <div id="repos"></div>;
}
createRepoWidget({
username: 'your-org',
containerId: 'oss-repos',
sortBy: 'updated',
forked: false,
cardStyles: {
backgroundColor: '#0f1117',
borderRadius: '12px',
border: '1px solid #30363d',
boxShadow: '0 4px 12px rgba(0,0,0,0.4)'
},
textStyles: {
titleColor: '#58a6ff',
descriptionColor: '#8b949e'
},
onLoad: (repos) => console.log(`Rendered ${repos.length} repos`)
});
RepoWidget only accesses public repository data via unauthenticated requests. No private data is ever readable.
If you supply an optional auth token for higher rate limits, route requests through your own backend rather than including tokens in page source.
Add connect-src https://api.github.com; to your Content-Security-Policy if
your site uses CSP.
RepoWidget specializes. It doesn't try to be a charting library or a full design system.
| RepoWidget | GitHub Readme Stats | Manual HTML | |
|---|---|---|---|
| Live data | Yes | Yes (SVG) | No |
| Interactive / clickable | Yes | No | Yes |
| Full CSS control | Yes | Limited params | Yes |
| Setup time | <5 min | <5 min | Hours–days |
| Ongoing maintenance | None | None | Manual |
| Works in plain HTML file | Yes | Via <img> | Yes |
| Built-in caching | Yes (24 hr) | No | No |
Install via npm or drop the CDN link directly into your HTML. No bundler, no config file, no component architecture to learn.
# npm
npm install repowidget
# or via CDN
https://cdn.jsdelivr.net/npm/repowidget/dist/repoWidget.min.js
https://unpkg.com/repowidget/dist/repoWidget.min.js