Snap-Port is a zero-dependency TypeScript library designed to automate the display of GitHub projects on personal websites or portfolios.
The core philosophy is to use GitHub as your Single Source of Truth: by simply tagging your repositories, the library handles fetching, processing, caching, and rendering data, eliminating manual updates to your portfolio's code.
Snap-Port offers full control over what is displayed and how technologies are categorized:
- Discovery Tag: By default, the library looks for repositories tagged with
port, but you can define any custom tag during initialization. - Stack Filters (Topics): For automatic filters and search to work correctly, list your technologies (e.g.,
react,nodejs,css) in your GitHub repository topics. - Why avoid automatic "Language"?: Snap-Port ignores the default GitHub
languagefield to let you highlight the actual stack. This prevents a React project from being labeled merely as "HTML" or "JavaScript" due to build files, ensuring the filter reflects the real project stack.
Since the GitHub API does not return direct preview image links, Snap-Port implements an automatic generation logic:
To ensure each project has its own image, follow these rules:
- Preview File: Create a file named
preview.pngin the root of your repository. - Note: The filename must be exactly
preview.png(case-sensitive).
If the file is missing or a loading error occurs (such as Rate Limits), the library executes a cascading fallback strategy:
- GitHub Open Graph: Attempts to load the dynamic social card generated by GitHub.
- Safety Placeholder: If the request is blocked, it generates a neutral card with the project name via
placehold.co.
- Search Bar: Real-time text filtering (name, description, and topics).
- Filter Carousel: Dynamic carousel based on repository topics.
- Project Cards (16:9 Layout): Responsive cards with technology badges and action buttons (Code and Deploy).
- Image Aspect Ratio: To avoid cropping, save your
preview.pngfiles in 16:9 aspect ratio (e.g., 1280x720px). - Live Demo (Deploy): The "Acessar" (Visit) button only appears if the "Homepage" field is filled in your GitHub repository settings.
npm install snapportUse type="module" for modern ES module compatibility.
<!-- 1. Library Styles -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net">
<!-- 2. Logic and Initialization -->
<script type="module">
import { initPortfolio } from 'https://cdn.jsdelivr.net';
initPortfolio('your-username', {
tag: 'port', // Optional: defaults to 'port'
searchContainer: 'id-search', // Search container ID
filtersContainer: 'id-filters', // Filters container ID
projectsContainer: 'id-projects' // Projects grid container ID
});
</script>Adapt the UI to your theme by overriding these variables in your global CSS:
:root {
--ghp-accent: #333; /* Accent color (buttons/icons) */
--ghp-bg: #ffffff; /* Card background */
--ghp-text: #333; /* Main headings and text */
--ghp-text-light: #666; /* Descriptions and secondary text */
--ghp-border: rgba(226, 226, 228, 0.8); /* Borders */
--ghp-shadow: rgba(0, 0, 0, 0.1); /* Card shadows */
}Keep the search/cache logic but use your own design:
initPortfolio('your-username', {
projectsContainer: 'id-projects',
customCardTemplate: (repo) => `
<div class="my-custom-card">
<h4>${repo.name}</h4>
<p>${repo.description}</p>
<a href="${repo.htmlUrl}">View Source</a>
</div>
`
});Data is stored via localStorage for better performance:
- Persistence: Data cached for up to 2 hours.
- Isolation: Cache is separated by GitHub username.
Note: This is an independent open-source project. Feel free to contribute! If you find a bug or have a feature idea, opening an Issue or a Pull Request is the best way to help.
To learn how to collaborate with the code, please check our Contributing Guide.
Author: Guilherme Godoy (@guilhermegodoydev)