Create production-ready 1280×640 Open Graph preview images from public GitHub repositories directly in the browser, with zero build tooling and deterministic export behavior.
Note
This repository is a static front-end application with a minimal Python server for local development only.
- Features
- Tech Stack & Architecture
- Getting Started
- Testing
- Deployment
- Usage
- Configuration
- License
- Support the Project
- Client-side generation of GitHub social preview assets at fixed
1280×640dimensions. - Flexible repository input parser supporting both:
- Full URL format (for example,
https://github.com/owner/repo) - Shorthand format (
owner/repo)
- Full URL format (for example,
- Real-time metadata retrieval from the GitHub REST API, including:
- Repository name, owner, and description
- Default branch, creation year, and last update timestamp
- License metadata and repository size
- Language composition visualization using repository language byte statistics.
- Multiple visual themes and templates for post-branding consistency:
- Themes: blue, green, purple, orange, red, cyan
- Layouts:
grid,timeline,spotlight,minimal,compact
- High-quality export pipeline with both
PNGandJPEGoutput modes. - Sanitized, deterministic filenames for generated assets.
- Graceful fallback behavior when optional API calls fail (for example, language endpoint degradation).
- Browser-native runtime with no mandatory backend service for production hosting.
- Security and quality automation integrated through GitHub Actions (linting, static analysis, scorecard).
Tip
This project is ideal for release announcements, changelog promotion, repository showcases, and portfolio posts where visual consistency matters.
- HTML5 for semantic structure and rendering surface.
- CSS3 for component styling, theme tokens, and card composition.
- Vanilla JavaScript (ES Modules) for modular app logic and DOM orchestration.
- Python 3 for local static file serving (
server.py). - GitHub REST API (
/repos/{owner}/{repo}and languages endpoints) for metadata hydration. html2canvas(loaded from CDN) for DOM-to-image rasterization.
.
├── index.html
├── server.py
├── LICENSE
├── CONTRIBUTING.md
├── README.md
├── assets
│ ├── css
│ │ └── styles.css
│ ├── js
│ │ ├── app.js
│ │ ├── constants.js
│ │ ├── dom.js
│ │ ├── export.js
│ │ ├── github.js
│ │ └── utils.js
│ └── vendor
│ └── gif.js
├── Image
├── trigger action
│ └── trigger_action.py
└── .github
├── FUNDING.yml
├── labels.yml
├── dependabot.yml
├── pull_request_template.md
├── ISSUE_TEMPLATE
│ ├── bug_report.yml
│ └── feature_request.yml
└── workflows
├── ai-issue.yml
├── dependabot-auto-merge.yml
├── label-sync.yml
├── lint.yml
├── sast.yml
└── scorecard.yml
- Frontend-first execution model
- All core functionality runs in the browser to minimize operational overhead.
- Deployment remains static-host friendly (GitHub Pages, Netlify, object storage, CDN).
- Module boundary separation
- API access, rendering, exports, constants, and parsing utilities are isolated in dedicated files.
- This reduces coupling and simplifies targeted maintenance.
- Deterministic output dimensions
- Fixed
1280×640export dimensions ensure predictable OG-style rendering.
- Fixed
- Resilient metadata pipeline
- Non-critical failures (such as language endpoint issues) do not block primary preview generation.
- Minimal local tooling requirements
- Python’s standard library HTTP server avoids mandatory Node bundlers for contributors.
flowchart LR
A[User Input: owner/repo or URL] --> B[utils.parseInput]
B -->|Valid| C[github.fetchRepository]
C --> D[github.fetchLanguages]
C --> E[dom.renderRepository]
D --> F[dom.renderLanguages]
E --> G[app.applyTheme/applyTemplate]
F --> G
G --> H[Live Preview Card]
H --> I[export.downloadPreview]
I --> J[html2canvas Rasterization]
J --> K[PNG or JPEG Download]
B -->|Invalid| L[User-facing Status Error]
Important
Unauthenticated GitHub API calls are rate-limited. For heavy usage, consider adding a proxy service with token-based requests and cache controls.
Python >= 3.9(recommended3.11+) for local static hosting.- A modern browser with ES Module support (Chrome, Edge, Firefox, Safari).
- Internet connectivity for:
- GitHub API requests
- External font assets
html2canvasCDN delivery
git clone https://github.com/<your-org-or-user>/github-social-preview-generator.git
cd github-social-preview-generatorStart the local development server:
python server.pyOpen the application:
http://127.0.0.1:8000
Warning
Loading index.html with a file:// URL can break ES module imports in some browsers. Always use python server.py during local development.
The repository currently relies on syntax validation and CI automation rather than a dedicated unit-test harness.
Run local checks:
# Python syntax validation
python -m py_compile server.py "trigger action/trigger_action.py"
# JavaScript syntax checks
node --check assets/js/app.js
node --check assets/js/constants.js
node --check assets/js/dom.js
node --check assets/js/export.js
node --check assets/js/github.js
node --check assets/js/utils.jsCI workflows in .github/workflows/ provide additional quality gates:
lint.ymlfor lint/static checkssast.ymlfor CodeQL static analysisscorecard.ymlfor OpenSSF scorecard evaluation
Caution
Keep CI workflow assumptions synchronized with repository structure to avoid false negatives when directories evolve.
Deploy index.html and the assets/ directory to any static host:
- GitHub Pages
- Netlify
- Vercel (static mode)
- S3 + CloudFront
- NGINX or Apache static site hosting
- Configure caching for static files (
assets/*) with immutable cache headers where possible. - Consider API proxying if you need:
- Higher request limits
- Authenticated API access
- Centralized observability and request telemetry
- Pin third-party runtime dependencies and external assets to stable versions.
- Apply CSP headers compatible with required GitHub API and CDN/font origins.
This repository includes GitHub Actions workflows for:
- Security analysis (
CodeQL,OpenSSF Scorecard) - Lint and static checks
- Repository automation (labels, dependency management, issue automation)
- Open the app in your browser.
- Enter either
owner/repoor a full GitHub repository URL. - Click the generate action to fetch metadata.
- Choose a theme and layout template.
- Export as
PNGorJPEG.
import { parseInput } from './assets/js/utils.js';
import { fetchRepository, fetchLanguages } from './assets/js/github.js';
async function buildPreviewModel(input) {
// Parse and normalize input into owner/repo pair.
const parsed = parseInput(input);
if (!parsed) throw new Error('Invalid repository reference');
// Fetch primary repository metadata.
const repository = await fetchRepository(parsed.owner, parsed.repo);
// Fetch and rank repository languages by byte count.
const languages = await fetchLanguages(repository.languages_url);
// Return model used by the rendering layer.
return {
fullName: `${repository.owner.login}/${repository.name}`,
description: repository.description ?? 'No description provided.',
defaultBranch: repository.default_branch,
topLanguages: languages.map(([name]) => name),
};
}import { downloadPreview } from './assets/js/export.js';
downloadPreview({
type: 'png', // or 'jpeg'
button: document.getElementById('btn-png'),
captureElement: document.getElementById('capture'),
repoDisplayElement: document.getElementById('o-repo-display'),
});Primary constants are declared in assets/js/constants.js:
GITHUB_API_BASE_URL: Base repository API URL.DEFAULT_THEME: Startup theme key.THEMES: Theme palette/token mapping.LANG_COLORS: Language badge color mapping.
server.py uses configurable constants:
HOST(default127.0.0.1)PORT(default8000)
Edit these values directly to match your local environment.
The automation script trigger action/trigger_action.py expects the following environment variables in CI contexts:
GITHUB_TOKENGH_MODELS_TOKENREPOSITORYEVENT_NAMECOMMIT_SHAPR_NUMBERALLOWED_USER
Example .env template for CI-like local runs:
GITHUB_TOKEN=ghp_xxx
GH_MODELS_TOKEN=ghm_xxx
REPOSITORY=owner/repo
EVENT_NAME=pull_request
COMMIT_SHA=<sha>
PR_NUMBER=1
ALLOWED_USER=<github-username>Note
The front-end application itself does not require a .env file for normal local usage.
This project is licensed under the MIT License. See LICENSE for full terms.
If you find this tool useful, consider leaving a star on GitHub or supporting the author directly.







