PILY CT
ALL PROJECTS

NimbusCast.

A weather app that pairs live forecasts for any city with a poem matched to its sky. React front end, Express API on Vercel serverless.

ROLE
Full-Stack Engineer: design, frontend, API, deployment
TEAM
Solo
DATE
Oct 2023 to Nov 2023
TRACK
Full-Stack
STACK
React, TypeScript, Express, Vercel, Tailwind CSS
FIG. 03A SCREENSHOT
NimbusCast showing current weather, hourly and daily forecast, and a matched poem over a weather-specific background

FIG. 03B ARCHITECTURE

  • React SPA (Vite), frontend. Connects to Express on Vercel Functions (/weather · /poem). See note 3.
  • City search, frontend. Connects to Express on Vercel Functions (/cities/suggestions). See note 5.
  • Express on Vercel Functions, backend. Connects to Response cache (GEO · WEATHER · FORECAST), Poem ranker + fallback (KEYWORD). See note 1.
  • Response cache, storage. Connects to OpenWeatherMap (ON MISS). See note 2.
  • Poem ranker + fallback, backend. Connects to PoetryDB (5S TIMEOUT). See note 4.
  • OpenWeatherMap, external.
  • PoetryDB, external.

NOTES

  1. Decision

    I wrote one Express app and exported it as a Vercel serverless function, with a small dev.ts that runs the same app on a port locally. Production and local development share the same routes, and every /api route goes through a per-IP rate limiter first.

  2. Trade-off

    I let Vercel reuse a weather answer for 5 minutes, since the data barely changes in that time. Repeat searches come back about 2.5 times faster and don't use my free API quota. The trade-off is that the weather can be up to 5 minutes old.

  3. What I got wrong

    At first the whole page waited on a single loading flag, so the weather stayed hidden until the third-party poem API answered. Now the weather renders right away, the poem loads on its own, and a failed refetch keeps the last good data on screen.

  4. Failing gracefully

    The ranker asks PoetryDB for 5 random poems and picks the one that uses the weather word most often, so 'clouds' also matches 'cloud'. If PoetryDB fails or has no match, it serves one of 10 local poems instead of an error.

  5. Search that doesn't race

    Suggestions wait 300 ms after you stop typing. Each new keystroke cancels the previous request, so an old, slow response can't overwrite a newer one.

RESULTS

REPEAT SEARCH, FROM VERCEL'S EDGE CACHE
0.1s
MEDIAN FIRST SEARCH (3 UPSTREAM CALLS)
0.27s
UPSTREAM CALLS ON A REPEAT WITHIN 5 MIN
0
NEXT PROJECTDocument Memory Agent

PROJECT 08 / 08