# How to Build a Weather API with Express and Vercel

**Author:** Jeff See, Ismael Rumzan

---

To provide real-time weather data, you need to handle API integration, error handling and automatic scaling. With Vercel functions and Express, you can build a production-ready weather API in minutes.

In this tutorial, you will build and deploy a weather API route using the Open-Meteo API that:

1. Accepts a city name and geocodes it to coordinates
   
2. Fetches current weather data from the Open-Meteo API
   
3. Returns temperature, humidity, wind speed, and other weather metrics with optional metric/imperial unit conversion
   

## Prerequisites

- Node.js and pnpm installed locally
  
- A Vercel account
  
- Basic understanding of Express and async/await in TypeScript
  

## Build the Weather API

### 1\. Create your Express project

Start with the [Express starter](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fvercel%2Ftree%2Fmain%2Fexamples%2Fexpress&template=express) template. Once your the project is deployed on Vercel, clone the repository locally.

You can also create the project locally using the Vercel CLI with the following command

`vc init express`

### 2\. Add the Weather endpoint

Add the weather endpoint after your existing routes:

``app.get('/api/weather/:city', async (req, res) => { try { const city = req.params.city const units = req.query.units as string | undefined // Normalize units parameter const normalizedUnits = units === 'imperial' ? 'imperial' : 'metric' // Step 1: Geocode city to get coordinates const geoParams = new URLSearchParams({ name: city, count: '1', language: 'en', format: 'json' }) const geoResponse = await fetch(`https://geocoding-api.open-meteo.com/v1/search?${geoParams}`) if (!geoResponse.ok) { return res.status(geoResponse.status).json({ error: 'Failed to fetch geocoding data' }) } const geoData = await geoResponse.json() if (!geoData.results || geoData.results.length === 0) { return res.status(404).json({ error: `City '${city}' not found` }) } const location = geoData.results[0] const { name, country, latitude, longitude } = location // Step 2: Fetch current weather data const weatherParams: Record<string, string> = { latitude: latitude.toString(), longitude: longitude.toString(), current: 'temperature_2m,relative_humidity_2m,apparent_temperature,wind_speed_10m', timezone: 'auto' } // Add unit parameters for imperial if needed if (units === 'imperial') { weatherParams.temperature_unit = 'fahrenheit' weatherParams.wind_speed_unit = 'mph' } const weatherUrlParams = new URLSearchParams(weatherParams) const weatherResponse = await fetch(`https://api.open-meteo.com/v1/forecast?${weatherUrlParams}`) if (!weatherResponse.ok) { return res.status(weatherResponse.status).json({ error: 'Failed to fetch weather data' }) } const weatherData = await weatherResponse.json() // Return structured weather data res.json({ city: name, country, latitude, longitude, units: normalizedUnits, current: weatherData.current }) } catch (error) { console.error('Weather API error:', error) res.status(500).json({ error: 'Failed to fetch weather data', message: error instanceof Error ? error.message : 'Unknown error' }) } })`` ### 3\. Test the route locally Install the dependencies and launch the application in dev mode: `vercel dev` Use `curl` to test the API route: `# Test with default metric units curl http://localhost:3000/api/weather/london # Test with imperial units curl "http://localhost:3000/api/weather/san%20francisco?units=imperial"` ### 4\. Deploy to Vercel - Push the changes to your remote repository or run the `vercel` cli command    - Vercel will create a new preview deployment for your to test    - Merge to main branch to deploy to Production    > When you deploy an Express app to Vercel, the application becomes a single [Vercel Function](https://vercel.com/docs/functions) and uses [Fluid compute](https://vercel.com/docs/fluid-compute) by default.

## Summary

In this tutorial, you’ve built a real-time weather API using Express on Vercel.

You learned to:

- Structure a dynamic API route and integrate external APIs
  
- Deploy the app to Vercel as a function for automatic scaling
  

For a production application, make sure that you use a weather API that will not be rate limited based on the amount of traffic that you are expecting.

## Next steps

### Explore references

- [Explore the Express on Vercel docs](https://vercel.com/docs/frameworks/backend/express)
  
- [Express documentation](https://expressjs.com/)
  
- [Vercel Functions](https://vercel.com/docs/functions)

---

[View full KB sitemap](/kb/sitemap.md)
