A 100% reliable, zero-runtime-dependency GitHub Contribution Heatmap for React & Static Sites.
The popular react-github-calendar library relies on proxy APIs that frequently suffer from rate limits and downtime, breaking portfolios everywhere. Serverless GitHub Calendar completely reimagines this architecture.
Instead of fetching data on page load, a GitHub Action queries the GraphQL API on a schedule and injects a static JSON file directly into your build.
- 🟢 100% Uptime: Your heatmap data is served statically from your own domain. If GitHub's API goes down, your site stays up.
- ⚡️ Zero Runtime Cost: No network requests to third-party proxies. Instant rendering.
- 🎨 Modern Theming: Built-in support for native CSS variables (
color-mix) for flawless Tailwind and Dark Mode integration. - 📦 Ultra Lightweight: Zero dependencies.
Drop this workflow into your static site repository at .github/workflows/contributions.yml. It fetches your data every 12 hours and saves it to your public folder.
name: Fetch Contributions
on:
schedule:
- cron: '0 */12 * * *'
workflow_dispatch:
jobs:
update-heatmap:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- uses: FaizPalwala/serverless-github-calendar/packages/serverless-github-calendar-action@v1.0.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
username: your-github-username
output-file: public/contributions.json
- uses: stefanzweifel/git-auto-commit-action@v7
with:
commit_message: "chore: update github heatmap data"
file_pattern: public/contributions.jsonInstall the ultra-lightweight component:
npm install serverless-github-calendarUse it anywhere in your React, Next.js, or Astro application:
import { Heatmap } from 'serverless-github-calendar';
import 'serverless-github-calendar/style.css'; // Optional default themes
export default function Portfolio() {
// Automatically loads '/contributions.json' from your public folder
return <Heatmap />;
}The component uses CSS variables for theming, meaning it natively responds to your app's global stylesheets without requiring heavy JavaScript theme providers.
/* Add this to your global CSS */
:root {
--serverless-github-calendar-color-0: #ebedf0;
--serverless-github-calendar-color-1: #9be9a8;
--serverless-github-calendar-color-2: #40c463;
--serverless-github-calendar-color-3: #30a14e;
--serverless-github-calendar-color-4: #216e39;
}
.dark {
--serverless-github-calendar-color-0: #161b22;
--serverless-github-calendar-color-1: #0e4429;
--serverless-github-calendar-color-2: #006d32;
--serverless-github-calendar-color-3: #26a641;
--serverless-github-calendar-color-4: #39d353;
}- Add the GitHub Action workflow to your repository.
- Swap the dependency:
npm uninstall react-github-calendar && npm i serverless-github-calendar. - Replace
<GitHubCalendar username="..." />with<Heatmap />.
Done. You now have a faster, un-breakable portfolio.
By default, the Action uses the standard GITHUB_TOKEN, which only fetches public contributions. To include your private commits, you can pass a Personal Access Token (PAT).
Step 1: Generate a Fine-Grained PAT (or classic PAT with read:user scope) and save it as a Repository Secret (e.g. HEATMAP_PAT).
Step 2: Swap the token in your workflow:
- uses: FaizPalwala/serverless-github-calendar/packages/serverless-github-calendar-action@v1.0.0
with:
github-token: ${{ secrets.HEATMAP_PAT }}
username: your-github-usernameWarning
Security Best Practice: If your portfolio repository is public, navigate to Settings > Actions > General and ensure "Require approval for all outside collaborators" is enabled. This prevents malicious Pull Requests from executing workflows that could expose your PAT. The Action masks the token in logs by default.
Because this library relies on statically injected data, your site must deploy for the heatmap to update. By default, the GitHub Action commits the fresh contributions.json to your repository, which automatically triggers a build on Vercel/Netlify.
Is this bad? No. Running the cron job every 12 hours results in 2 deploys per day (~60 deploys per month). A static portfolio takes about 1 minute to build, meaning you'll use roughly 60 build minutes per month (just 1% of Vercel's 6,000 free-tier minutes).
How to Opt-Out (Save Build Minutes) If you are heavily constrained on build minutes, you have two options:
- Reduce the Cron Frequency: Change the cron schedule to
0 0 * * *to run only once per day. - Skip CI: You can tell Vercel/Netlify to ignore the commit entirely by adding
[skip ci]to the commit message in your workflow:
- uses: stefanzweifel/git-auto-commit-action@v7
with:
commit_message: "chore: update github heatmap data [skip ci]"
file_pattern: public/contributions.json(Note: If you use [skip ci], your heatmap will only update when you push other code changes to your portfolio!)
Want to display your heatmap on your GitHub Profile README? Because profile READMEs only support raw images, you can configure the Action to generate an SVG directly.
- uses: FaizPalwala/serverless-github-calendar/packages/serverless-github-calendar-action@v1.0.0
with:
username: your-github-username
output-svg: public/heatmap.svgYou can then embed the SVG in any markdown file: 
The Action automatically calculates your Current Streak and Longest Streak from the past year of contributions. This data is cleanly embedded directly into the output JSON and the SVG rendering, allowing you to showcase your commit consistency effortlessly.
If you prefer not to configure CSS variables manually, you can import one of our pre-packaged themes instantly.
// Choose one of the following:
import 'serverless-github-calendar/themes/dracula.css';
import 'serverless-github-calendar/themes/github-dark.css';
import 'serverless-github-calendar/themes/github-light.css';For Next.js App Router users, we provide a dedicated Server Component. It bypasses client-side fetches entirely by reading the JSON file directly from your server's filesystem, resulting in zero client-side JavaScript overhead.
import { ServerHeatmap } from 'serverless-github-calendar/rsc';
export default function Page() {
// Reads the JSON file instantly on the server via fs.readFileSync
return <ServerHeatmap />;
}Q: My calendar is empty or missing days?
A: Ensure your GitHub Action ran successfully. If you have private commits, make sure you followed the 🔒 Include Private Contributions setup using a PAT instead of the default token.
Q: Does this work with any framework?
A: The <Heatmap /> component works with any React-based framework (Next.js, Vite, CRA, Astro via @astrojs/react).
Pull requests are welcome! If you want to add a new theme or fix a bug:
- Clone the repo and run
npm install. - Navigate to
/demoand runnpm run devto test your changes locally. - Open a Pull Request!
If this library saved your portfolio from proxy downtime, consider supporting the project!
MIT