Harshit Sharma
All work

Web AppQ2 2021Solo build

Iplheat

Every bit of IPL action — updates, videos and live scores in one destination.

The Iplheat video feed — a match-highlight card with a play button under the site header.

The build

Live scores, updates and video in one place — and my first project built around somebody else's data.

Problem

Following a tournament means four tabs: one for the score, one for highlights, one for news, one for fantasy. Each reloads on its own schedule and none of them knows about the others. For a six-week tournament, that's a lot of friction for something people do every evening.

Constraints

  • The data isn't mine. Scores came from a public API, on its schedule, with its rate limits and its outages. Everything about the app's freshness was bounded by someone else's service.
  • Traffic is spiky by definition. Nothing for twenty-two hours, then everything at once when a match starts.
  • Read-only. No accounts, no writes — which removed most of the usual problems and made the remaining one, caching, the whole project.

Approach

An Express server that fetches from the upstream score API, caches the response, and serves every visitor from that cache rather than proxying each request through:

js
// One upstream call per interval, however many visitors are watching.
let cache = { at: 0, data: null };

async function scores() {
  if (Date.now() - cache.at < 30_000) return cache.data;
  cache = { at: Date.now(), data: await fetchUpstream() };
  return cache.data;
}

Trivia and a fantasy corner sit alongside the feed — static content whose only job is to be worth staying on the page for during the twenty minutes between innings.

Tradeoffs

  • A thirty-second cache over live polling. Every visitor sees a score up to thirty seconds old, and the upstream API sees two requests a minute instead of two thousand. For cricket, thirty seconds is inside the delay of the broadcast anyway.
  • Server-side caching over client-side. One shared cache means the hundredth visitor is as cheap as the first. It also means a single process holding state, which doesn't survive being scaled horizontally — irrelevant at one instance, wrong the moment it isn't.
  • No accounts. Removed auth, storage, and privacy entirely. It also removed any way to build the feature people actually want, which is a fantasy team that persists.

Outcome

It served a tournament: scores, updates, and enough around them to be worth opening. The lesson that stuck was about dependency — when the interesting data belongs to someone else, your product's real design constraint is their rate limit, and caching stops being an optimisation and becomes the architecture.

Decisions

  • Caching upstream responses over proxying each request. Chosen because a free-tier API key does not survive a match-day crowd. Against it: an in-process cache is invisible state that breaks silently if the app is ever run as more than one process.
  • A public API over scraping. Chosen for a stable contract and no legal grey area. Against it: the data is whatever the API offers, and the ball-by-ball detail I wanted wasn't in it.
  • Static trivia and fantasy over a real fantasy game. Chosen to keep a read-only app read-only. Against it: it's the feature that would have brought people back daily, and it's the one that isn't there.

Stack

  • Node.js
  • Express.js
  • JavaScript
  • REST API
  • Materialize CSS
  • The Lecture Lense workspace — a lecture playing above a chaptered time rail, the corrected transcript on the left, and a chat answer on the right with a timestamp citation.

    Lecture Lense

    Turns any recording into searchable, timestamp-cited notes.

  • Chitter's landing page — headline, a Join Chitter Now button, and a phone mockup of the feed.

    Chitter

    A mini social app that lets users sign up, log in and post whatever is on their mind.

  • A live Heckfree profile — avatar and the handle meharshit above seven stacked link rows, on a peach-to-purple gradient.

    Heckfree

    Users get a public profile that showcases all of their links in one place.

esc

Pages

Home/
Work/work
Blog/blog
About/about
Uses/uses
Contact/contact
Bucket list/bucket-list
Guestbook/guestbook
Résumé/resume
Privacy/privacy
Terms/terms

Projects

Lecture LenseQ3 2026
ChitterQ1 2023
HeckfreeQ3 2022
CoscholarsQ3 2022
JsswireQ2 2022
JssconnectQ1 2022
QuizTownQ4 2021
IplheatQ2 2021
TechkartQ4 2020

Posts

Passport.js auth patterns I keep reaching for7 min read
How To Create A README For GitHub Profile3 min read
↑↓ navigate↵ openesc close