Skip to main content

Command Palette

Search for a command to run...

Crafting a Cutting-Edge Weather App: A Journey with React, Tailwind, Vite, and GSAP

Updated
5 min read
Crafting a Cutting-Edge Weather App: 
A Journey with React, Tailwind, Vite, and GSAP

Weather apps are one of the most common beginner-friendly projects, but turning them into something production-grade is another story. When I took on the Frontend Mentor Weather App Challenge, I decided not just to build a simple app that shows the temperature, but to go deeper:

  • Add progressive web app (PWA) features

  • Make it responsive across devices

  • Enhance the user experience with animations

  • Provide unit switching & custom dropdowns

  • Include favorites, compare lists, and toast notifications

  • And even a unique 5-second GSAP intro animation to make it stand out.

In this article, I’ll take you through the process of building this project, the tools and techniques I used, the challenges I faced, and the lessons I learned along the way.


Why Build Another Weather App?

It’s fair to ask: why a weather app?

The truth is, weather apps are the perfect sandbox for practicing API integration, state management, UI design, and accessibility. Almost every feature you might need in a larger app—searching, persisting data, handling errors, toggling views—can be prototyped in a weather app.

For me, the motivation was twofold:

  1. To practice building a PWA from scratch, and

  2. To polish a project to portfolio-ready quality instead of just a quick demo.


Tech Stack & Tools

Here’s what I used to build the app:

  • React – The backbone of the UI

  • Vite – Lightning-fast dev/build tool

  • Tailwind CSS – Utility-first styling

  • React Hot Toast – For in-app notifications

  • GSAP – For animated text intro and transitions

  • Vite PWA plugin – To make the app installable and offline-friendly

  • Open-Meteo API – Free weather API with hourly/daily forecasts


Core Features

🔎 City Search with Debouncing

One of the first features was a search bar to look up cities. A common mistake is making API calls on every keystroke. Instead, I implemented debouncing, so the API only gets called once the user pauses typing.

const [query, setQuery] = useState("");
const debouncedQuery = useDebounce(query, 500);

useEffect(() => {
  if (debouncedQuery) {
    fetchWeather(debouncedQuery);
  }
}, [debouncedQuery]);

This not only reduces API calls but also improves responsiveness.


🌤 Current Weather Display

The main card shows:

  • Current temperature

  • Weather icon

  • Location details (city, country)

  • Extra metrics: “feels like”, humidity, wind speed, precipitation

This gave users at-a-glance clarity while still letting them drill down into more data.


📅 7-Day Forecast

The daily forecast section shows each day’s:

  • High/low temperatures

  • Weather icons

I structured it with a horizontal scrollable card layout so users on mobile could swipe through comfortably.


🕒 Hourly Forecast with Scrollable Cards

This was one of the trickiest parts. The hourly forecast for a selected day is displayed in a scrollable container. To make it professional:

  • I hid default browser scrollbars with custom Tailwind classes.

  • Each hourly card shows the weather icon, time, and temperature.

  • The user can switch days via a dropdown, which filters the hourly list dynamically.

<div className="scrollbar-hide mt-4 flex h-[620px] flex-col gap-4 overflow-y-auto">
  {filteredHourlyForecast?.map((hour, index) => (
    <HourlyCard key={hour.time} hour={hour} i={index} />
  ))}
</div>

This created a clean, card-based UI while keeping it functional.


⚙️ Units Dropdown

I wanted to go beyond the typical “Celsius ↔ Fahrenheit” toggle. The dropdown allows:

  • Switching the entire system (metric ↔ imperial)

  • Individually changing:

    • Temperature (°C / °F)

    • Wind speed (km/h / mph)

    • Precipitation (mm / in)

To achieve this, I built a dropdown inspired by professional Shadn UI.


⭐ Favorites & Compare

Two features that added polish were:

  • Favorites – Save cities to localStorage for quick access later

  • Compare – Add cities to a “compare list” at the bottom of the screen

When a city is added to compare, a toast notification appears:

“Added to compare list at the bottom, select another city too”

This subtle feedback improves UX tremendously.


📱 PWA Support

A huge goal was making this installable. Using vite-plugin-pwa, I:

  • Added a manifest with icons of all required sizes

  • Ensured rich install banners show up

This means users can add it to their home screen and even use it with no network.


✨ GSAP Intro Animation

Here’s where the app really stands out. I wanted the first 5 seconds to feel cinematic. Using GSAP’s , I animated the app title.

  • Fades in smoothly

  • After 5 seconds, the intro transitions into the main weather dashboard.

This animation is subtle but memorable. It sets the app apart from most weather apps that just jump into content.


Challenges & Solutions

1. Scrollbar Styling

Browsers handle scrollbars differently, and Tailwind doesn’t support this natively. I used the scrollbar-hide custom class to remove them and applied custom classes for consistent styling.

2. Dropdown UX

The default dropdown looked from Shadncn UI, ensuring it was responsive and accessible.

3. PWA Manifest Icons

Initially, the install banner looked broken because I hadn’t provided icons in all required sizes. Tools like RealFaviconGenerator helped fix that.

4. API Rate Limits

The Open-Meteo API is free but can fail if spammed. Debouncing search input was crucial to avoid hitting rate limits.


What I Learned

This project reinforced several concepts:

  • API integration best practices (debouncing, error handling)

  • PWA setup (manifest, service workers, caching)

  • Animations for UX (GSAP intro, smooth dropdowns, hover states)

  • State management & persistence with localStorage

  • UI polish (toasts, icons, scrollbars, responsive layout)

The biggest lesson was: little details make a big difference. A toast here, a smooth intro animation there, custom icons—these elevate a simple weather app into something that feels professional.


Future Improvements

Some areas I’d like to improve:

  • Pre-caching API responses for offline usage

  • Adding historical weather charts with Recharts or Chart.js

  • More advanced comparison view (graphs comparing two cities side by side)

  • Better accessibility support for screen readers

  • Optimizing animations for performance on low-end devices


Conclusion

Building this weather app was more than just an exercise—it was a chance to bring together frontend best practices, PWA technology, and UI polish into one cohesive project.

From GSAP-powered intro animations to scroll handling, and toast notifications, every feature was an opportunity to push myself closer to production-quality work.

If you’re learning frontend development, I highly recommend trying something similar. Don’t just stop at “fetch and display weather.” Add persistence, add interactivity, add polish. That’s where the learning truly happens.


Live demo: https://vite-weather-app-sigma.vercel.app/
📂 Source code: https://github.com/Skyz03/Vite-Weather-App

More from this blog

A

Aakib'z Studio

121 posts

I share practical insights on powerful development frameworks, focusing on Next.js for modern web apps and Flutter for efficient cross-platform mobile app development.