Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Weather Laravel Package

gnahotelsolutions/laravel-weather

Laravel Weather offers a simple, configurable way to fetch current conditions and forecasts in Laravel apps. Integrate weather data with a clean API, caching support, and flexible settings for your preferred weather service. Ideal for dashboards, travel sites, and location-aware features.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a thin, single-purpose wrapper around OpenWeatherMap's current weather endpoint (/data/2.5/weather). It is a small package (38★), so there is no dashboard, no DTO layer, and no polling — just a config file, a facade, and an array response.

Install and wire it up in three steps:

composer require gnahotelsolutions/laravel-weather
php artisan vendor:publish --tag=weather-config   # publishes config/weather.php

Then add the key from openweathermap.org to .env:

OPEN_WEATHER_MAP_API_KEY=your_key_here

Where to look first:

  1. config/weather.php — this is the whole contract: the endpoint URL, the api_key, and the query defaults (units, lang). If something is wrong, it is almost always here.
  2. The facade Gnahotelsolutions\LaravelWeather\Facades\Weather — this is the entire public surface. You will not find much else.
  3. The OpenWeatherMap API docs for the current-weather endpoint, because the package returns the raw response array essentially untouched.

First use case — show current weather in a controller:

use Gnahotelsolutions\LaravelWeather\Facades\Weather;

Route::get('/weather/{city}', function (string $city) {
    $weather = Weather::get($city); // returns the decoded JSON array

    return view('weather', [
        'city'        => $weather['name'],
        'temperature' => $weather['main']['temp'],
        'description' => $weather['weather'][0]['description'],
    ]);
});

That is the entire happy path. The package does one thing, so if the task grows beyond "current weather in a city," you will outgrow it quickly.

Note: confirm the exact method name (get, find, etc.) against the repo's README for the version you install — the API is small and the package has not changed since 2021.


Implementation Patterns

Wrap it behind your own service

Do not scatter Weather::get(...) across controllers. Because the response is a raw array and the package is unmaintained, isolate it so you can swap in a maintained client (or Laravel's Http facade directly) later without touching callers.

namespace App\Services;

use Gnahotelsolutions\LaravelWeather\Facades\Weather;

class CurrentWeather
{
    public function forCity(string $city): array
    {
        return Weather::get($city);
    }
}

Cache aggressively — this is the single biggest win

OpenWeatherMap's free tier is rate-limited, and current weather changes slowly. Cache by city (or by coordinates) for 5–15 minutes:

use Illuminate\Support\Facades\Cache;

$weather = Cache::remember("weather:{$city}", now()->addMinutes(10), function () use ($city) {
    return Weather::get($city);
});

Key on the inputs (city + units + lang), not on the current time, or you will get a cache miss every minute.

Prefer the raw Http facade for non-trivial needs

If you need hourly/daily forecasts, multiple cities in one call, geocoding, or error-code handling, skip the wrapper and call the API directly — it will be less code than fighting the package's limited surface:

use Illuminate\Support\Facades\Http;

$response = Http::get('https://api.openweathermap.org/data/2.5/weather', [
    'q'     => $city,
    'appid' => config('weather.api_key'),
    'units' => 'metric',
])->throw()->json();

This is the pattern most teams eventually migrate to. The wrapper is a reasonable starting point for a single widget; the Http facade is the sustainable pattern.

Refresh weather on a schedule

If you show weather on a dashboard, do not hit the API during the request. Fetch on a schedule and expose it from cache or the DB:

// app/Console/Kernel.php
$schedule->call(function () {
    foreach (config('weather.cities', []) as $city) {
        Cache::put("weather:{$city}", Weather::get($city), now()->addMinutes(15));
    }
})->everyTenMinutes();

Coordinates and other lookups

The OpenWeatherMap endpoint accepts q (city name), id (city id), lat/lon, and zip. Whatever the package exposes, map your domain inputs to those parameters and centralise the mapping — city-name lookups are ambiguous ("Springfield") and you will want to change strategy later.

Testing

Because the package ultimately makes an HTTP call, mock it at the HTTP layer with Http::fake() (if it uses the Laravel HTTP client) or a Guzzle handler stack (if it uses Guzzle directly — inspect the source). Then assert against a fixture array so tests do not depend on the network:

Http::fake([
    'api.openweathermap.org/*' => Http::response(['name' => 'Milan', 'main' => ['temp' => 21.5]]),
]);

If the package bypasses Http, wrap it behind your service and mock your service in feature tests; keep one integration test that hits a recorded fixture.


Gotchas and Tips

The package is unmaintained (last release Sept 2021). Treat it as a vendored snippet, not infrastructure. Pin the exact version in composer.json, and assume you will fork or replace it. Do not let it get pulled anywhere you need guaranteed compatibility with a future Laravel/PHP release.

401 Unauthorized right after signup. New OpenWeatherMap API keys can take minutes to hours to activate. A brand-new key returning 401 is almost always activation, not your config.

Failures are not your domain errors. The wrapper does not give you typed exceptions — a bad city, an inactive key, and a network timeout may all surface differently. Wrap calls in try/catch and map the API's cod/message to your own response codes:

try {
    $weather = Weather::get($city);
} catch (\Throwable $e) {
    report($e);
    abort(502, 'Weather unavailable');
}

City names are ambiguous. London resolves fine; Springfield, Paris (Texas vs France), and any name with diacritics can resolve to the wrong place. If accuracy matters, use the OpenWeatherMap geocoding API to get a city id, then query by id — the wrapper's name lookup is fine for demos and unreliable for production.

Units and language are config/query defaults. temperature is Kelvin unless you set units=metric (Celsius) or imperial (Fahrenheit). Displaying 293.15 to a user is the classic first bug. Same for description — it defaults to English and needs lang for localization.

The response is an untyped array. There is no model or DTO, so $weather['main']['temp'] and friends can be missing (e.g., an error payload that did not throw) and you get a PHP warning. Guard with data_get() or the null-coalescing operator in views.

Cache keys must include units and lang. Otherwise a metric request can be served to a Fahrenheit page and vice versa.

Respect the free-tier quota. 60 calls/min and ~1M/month sounds generous, but a naive per-request call on a popular page will blow through it. Cache, batch in a scheduled job, and consider putting a short circuit breaker in front of the API.

Timezone trap. The dt field is UTC and the response's timezone is an offset in seconds, not a name. Do not Carbon::parse($weather['dt']) and assume local time; convert explicitly with the offset.

Extension point is limited. There is essentially one place to customise: config/weather.php. If you need retries, logging, custom exceptions, or a second endpoint, add that logic in your own service around the facade — not by editing the vendor package.

Migrate when it hurts. The moment you need forecasts, history, air quality, or reliable error handling, you have outgrown this package. A ~20-line Http-based client with a Cache::remember wrapper usually replaces it with less code and fewer surprises.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log