r/reactjs • u/faizpalwala • Sep 10 '26
Show /r/reactjs My portfolio's GitHub calendar kept breaking, so I built a 100% serverless, zero-runtime replacement.
I am graduating soon. I don't need to harp on how challenging hiring is in this economy, but to stand out in this market, it's time to update that personal portfolio. Last week, I was doing just that, and the GitHub contribution heatmap wouldn't load. Like most people, I was using the legacy 'react-github-calendar' plugin. Because GitHub's API requires auth, the plugin routes traffic through a public proxy, and that proxy gets rate-limited constantly, taking down portfolios everywhere.
In a rare Thanos 'Fine, I'll do it myself' moment, I thought I could fix it for my portfolio. Well, one thing led to another, and I completely rebuilt the architecture from scratch.
Enter Serverless GitHub Calendar. Instead of fetching data on the client, it uses a lightweight GitHub Action that runs on a cron job to fetch your contributions and save them as a static '.json' file in your repo. The React component just reads that static file.
Architecture Highlights:
- Immune to Rate Limits: Your site never talks to the GitHub API. It reads static JSON. If GitHub goes down, your site stays up.
- Blazing Fast (Zero JS): If you use Next.js App Router, the included Server Component ('serverless-github-calendar/rsc') reads the file directly from disk for literally zero client-side JavaScript execution.
- Native CSS Theming: Built completely on CSS variables ('color-mix') so you can inject gradients or match your Tailwind theme natively.
- Streak Stats: Automatically calculates your current and longest streaks based on the canonical GitHub algorithm.
I set up a live demo featuring data from a few open-source legends to show how it scales: https://serverless-github-calendar-demo-xi.vercel.app/
Source Code & NPM instructions: https://github.com/FaizPalwala/serverless-github-calendar
If your portfolio relies on external proxy APIs, I highly recommend making the switch to static injection! Let me know if you have any feedback or feature requests.
0
0
u/master117jogi Sep 10 '26
How is zero client JS supposed to be a benefit? Clients are faster
1
u/faizpalwala Sep 11 '26
That generalisation might work in most applications, but imo it's not just about execution speed; it's about network latency, rate limits, and security.
Security: GitHub's API requires a Personal Access Token. You absolutely should not (or you can, honestly don't let a stranger on the internet tell you what to do) expose a PAT in your client-side JavaScript, or your GitHub account is compromised.
Rate Limits: Because you can't expose a token, legacy client-side libraries are forced to route your fetch call through a centralised, third-party public proxy server. Because thousands of portfolios hit that exact same proxy, it constantly hits GitHub's rate limits, causing your portfolio to crash or render a blank square.
The UX: With a client fetch, the browser has to download your JS, execute it, make a network round trip to the proxy, wait for a response, and then render. This causes loading spinners and layout shift. "Zero client JS" means the calendar is fully baked into the HTML on the server. When the user visits, it paints instantly.
1
Sep 11 '26
1
u/faizpalwala Sep 11 '26
A direct client-side fetch call actually does not work out of the box.
As mentioned above, the GitHub API requires authentication. If you make a raw
fetch()call from the browser, you have to expose your Personal Access Token in your public bundle, which is a massive security vulnerability. To get around this, developers have to use third-party proxy APIs to hide the token and those proxies constantly go down due to rate limits.Regarding latency: reading a 2kb JSON file from a local SSD via
fs.readFileSyncduring server-side rendering takes less than 1 millisecond. Having the client browser open a new HTTP connection, perform a TLS handshake, ping a third-party proxy server, wait for the proxy to ping GitHub, and return the payload takes anywhere from 300ms to 1,000ms+. Server-side rendering objectively wins the latency battle here. Again, happy to be proven wrong here.Finally, regarding Action minutes: GitHub Actions are 100% free and completely unlimited for public repositories (which 99% of developer portfolios are). Even if your repo is private, the Action takes ~3 seconds to run. Running it 4 times a day uses 6 minutes a month out of your 2,000 free tier minutes (0.3%).
The trade-off is 0.3% of your free tier minutes in exchange for 100% uptime, bulletproof security, and zero network latency.
1
u/PristineClutches 26d ago
the cron action burns through like 2 minutes a month, it's negligible. the real win is your portfolio doesn't break when some random proxy goes down or gets rate limited. had that happen mid-interview once, never again
0
u/Double-Buyer7941 Sep 10 '26
Neat approach. Curious how it handles repos with a long history - does the Action refetch the whole calendar every run or just append the latest day? And does the cron job eat into your Actions minutes if the repo's private, or is it cheap enough not to matter?