/how-to-build-replit

How to Build a Weather application with Replit

Learn how to build a weather application with Replit in simple steps. Create, code, and deploy your own weather app easily using this guide.

Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

How to Build a Weather application with Replit

To build a weather application on Replit, you should create a simple Node.js + Express backend that fetches weather data from a public API (like OpenWeatherMap) and a lightweight frontend that displays it. Store your API key securely in Replit Secrets, use fetch to request data, and serve a static HTML file through Express. This approach works reliably on Replit, stays responsive, and avoids exposing sensitive keys to the browser.

 

Project Setup

 

  • Open Replit and create a new Repl using the "Node.js" template.
  • In the left sidebar, create a new folder named public. Inside that folder, create index.html and script.js.
  • Your main server file index.js is created by default — use this as your backend.
  • Go to the Replit sidebar ➜ "Secrets" (lock icon) ➜ add a new secret key named WEATHER_API_KEY with your OpenWeatherMap API key value.

 

Install Required Packages

 

npm install express node-fetch

 

Write the Backend (index.js)

 

You’ll use Express to serve both static files and a server endpoint to call the weather API. Replace everything inside index.js with the following code:

 

import express from "express"
import fetch from "node-fetch"

const app = express()
const PORT = process.env.PORT || 3000
const API_KEY = process.env.WEATHER_API_KEY  // stored securely

// Serve static files (the frontend)
app.use(express.static("public"))

// API endpoint that fetches weather data
app.get("/weather", async (req, res) => {
  const city = req.query.city
  if (!city) {
    return res.status(400).json({ error: "City required" })
  }

  try {
    const url = `https://api.openweathermap.org/data/2.5/weather?q=${encodeURIComponent(city)}&appid=${API_KEY}&units=metric`
    const response = await fetch(url)
    const data = await response.json()

    if (data.cod !== 200) {
      return res.status(data.cod).json({ error: data.message })
    }

    res.json({
      city: data.name,
      temperature: data.main.temp,
      condition: data.weather[0].description
    })
  } catch (err) {
    console.error(err)
    res.status(500).json({ error: "Failed to fetch weather data" })
  }
})

app.listen(PORT, () => {
  console.log(`Weather app running on port ${PORT}`)
})

 

Create the Frontend (public/index.html)

 

This is the part users will see. Paste this into public/index.html:

 

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Weather App</title>
</head>
<body>
  <h2>Weather Application</h2>
  <input id="cityInput" type="text" placeholder="Enter city name" />
  <button id="getWeatherBtn">Get Weather</button>
  <p id="result"></p>

  <script src="script.js"></script>
</body>
</html>

 

Frontend Logic (public/script.js)

 

Now, add simple browser-side JavaScript to handle the button click and display results:

 

// Selecting HTML elements
const button = document.getElementById("getWeatherBtn")
const input = document.getElementById("cityInput")
const result = document.getElementById("result")

button.addEventListener("click", async () => {
  const city = input.value.trim()
  if (!city) {
    result.textContent = "Please enter a city name."
    return
  }
  result.textContent = "Loading..."

  try {
    const response = await fetch(`/weather?city=${encodeURIComponent(city)}`)
    const data = await response.json()

    if (data.error) {
      result.textContent = `Error: ${data.error}`
      return
    }

    result.textContent = `${data.city}: ${data.temperature}°C, ${data.condition}`
  } catch (err) {
    result.textContent = "Unable to fetch weather data."
  }
})

 

Run and Test the App

 

  • Click the green “Run” button in Replit. Replit starts your Node.js server and shows a preview URL.
  • Enter a city name (e.g., "London") and click Get Weather.
  • If everything is set up correctly, you’ll see live temperature and weather conditions appear.

 

Practical Tips for Replit

 

  • Secrets: Never hard-code API keys — always store them in Replit’s Secrets tool.
  • Persistence: The Repl restarts sometimes when idle; don’t rely on in-memory data to persist.
  • Console logs: Use console.log() generously for debugging inside Replit’s built-in console.
  • Ports: Always listen on process.env.PORT — Replit expects that for the web preview to work.

 

This setup uses Replit in the way it’s intended — lightweight server with static frontend, secured secrets, and easy collaborative coding — perfectly suited for a small but real-world-style weather app.

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Contact Us

How to Build a Weather API Proxy Server with Node and Express


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Weather API Proxy Example</title>
</head>
<body>
  <h1>Weather App Server (Node + Express)</h1>

  <script type="module">
    import express from "express";
    import fetch from "node-fetch";

    const app = express();
    const PORT = process.env.PORT || 3000;
    const API_KEY = process.env.OPENWEATHER_API\_KEY;

    // Cache structure to avoid hitting API rate limits in Replit
    const cache = new Map();

    app.get("/api/weather/:city", async (req, res) => {
      const city = req.params.city.toLowerCase();
      const now = Date.now();
      const cached = cache.get(city);

      if (cached && now - cached.timestamp < 1000 _ 60 _ 5) {
        return res.json(cached.data);
      }

      try {
        const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${API_KEY}&units=metric`;
        const response = await fetch(url);
        if (!response.ok) throw new Error("API request failed");
        const data = await response.json();

        const structured = {
          location: data.name,
          temperature: data.main.temp,
          description: data.weather[0].description,
          humidity: data.main.humidity,
          wind: data.wind.speed,
          updatedAt: new Date().toISOString()
        };

        cache.set(city, { data: structured, timestamp: now });
        res.json(structured);
      } catch (err) {
        res.status(500).json({ error: "Unable to fetch weather data" });
      }
    });

    app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
  </script>
</body>
</html>

How to Create a Backend that Combines Weather Data and Geolocation in Replit


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Weather GeoLocation Proxy</title>
</head>
<body>
  <h1>Weather + Geolocation Backend Example</h1>

  <script type="module">
    import express from "express";
    import fetch from "node-fetch";

    const app = express();
    const PORT = process.env.PORT || 3000;
    const WEATHER_KEY = process.env.OPENWEATHER_API\_KEY;
    const GEO_KEY = process.env.OPENCAGE_API\_KEY;

    // Endpoint: user gives coordinates, server returns weather info with resolved city name
    app.get("/api/weather/coords", async (req, res) => {
      const { lat, lon } = req.query;
      if (!lat || !lon) return res.status(400).json({ error: "Missing lat/lon" });

      try {
        // Reverse geocode the city name
        const geoUrl = `https://api.opencagedata.com/geocode/v1/json?q=${lat}+${lon}&key=${GEO_KEY}`;
        const geoResponse = await fetch(geoUrl);
        if (!geoResponse.ok) throw new Error("Reverse geocoding failed");
        const geoData = await geoResponse.json();
        const city = geoData.results?.[0]?.components?.city || "Unknown location";

        // Fetch weather info
        const wUrl = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${WEATHER_KEY}&units=metric`;
        const wResponse = await fetch(wUrl);
        if (!wResponse.ok) throw new Error("Weather API failed");
        const weatherData = await wResponse.json();

        res.json({
          location: city,
          coordinates: { lat, lon },
          temp: weatherData.main.temp,
          desc: weatherData.weather[0].description,
          humidity: weatherData.main.humidity
        });
      } catch (err) {
        res.status(500).json({ error: err.message || "Server error" });
      }
    });

    app.listen(PORT, () => console.log(`Server ready on ${PORT}`));
  </script>
</body>
</html>

How to Schedule Automatic Weather Data Fetching with Node, Express, and Cron


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Weather Alert Scheduler</title>
</head>
<body>
  <h1>Scheduled Weather Data Fetcher (Node + Express + Cron)</h1>

  <script type="module">
    import express from "express";
    import fetch from "node-fetch";
    import cron from "node-cron";

    const app = express();
    const PORT = process.env.PORT || 3000;
    const WEATHER_API_KEY = process.env.OPENWEATHER_API_KEY;

    let latestData = {};

    async function fetchWeather(city = "London") {
      try {
        const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${WEATHER_API_KEY}&units=metric`;
        const res = await fetch(url);
        if (!res.ok) throw new Error("Weather API failed");
        const data = await res.json();
        latestData[city] = {
          temp: data.main.temp,
          desc: data.weather[0].description,
          updatedAt: new Date().toISOString()
        };
        console.log(`Updated weather cache for ${city}`);
      } catch (error) {
        console.error(`Error fetching weather for ${city}:`, error.message);
      }
    }

    cron.schedule("_/10 _ _ _ \*", () => {
      console.log("Scheduled weather refresh...");
      fetchWeather("London");
      fetchWeather("New York");
    });

    app.get("/api/weather/latest/:city", (req, res) => {
      const city = req.params.city;
      if (!latestData[city]) return res.status(404).json({ error: "No cached data" });
      res.json(latestData[city]);
    });

    app.listen(PORT, () => {
      console.log(`Server running on port ${PORT}`);
      fetchWeather("London");
      fetchWeather("New York");
    });
  </script>
</body>
</html>

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Contact Us
Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Best Practices for Building a Weather application with Replit

Building a weather app on Replit works best when you split cleanly between backend (a small Node.js or Python server handling API keys and weather data) and frontend (a simple HTML/JS page showing the weather). Store your weather API key in Replit Secrets, not in your code. Use the Replit web server to serve both static files (like HTML, CSS, JS) and your backend API route. Keep Replit’s always-on limits and timeout behavior in mind: use requests efficiently and don’t rely on background loops or cron jobs. Think of Replit like a live coding space that’s great for lightweight apps — not a full production hosting environment, but strong for prototyping and moderately used projects.

 

Project Structure and Planning

 

Create a basic folder structure like this:

weather-app/
├── index.js        // Your Node.js server (backend)
├── public/
│   ├── index.html  // Frontend HTML
│   ├── script.js   // Frontend JavaScript
│   └── style.css   // Optional styling
├── .replit         // Replit config file

Replit automatically runs index.js as your entry point for Node.js projects. The public directory will hold your client‑side files.

 

Setup Backend with Express.js

 

In index.js, you’ll use Express.js to create a simple web server and expose an endpoint that fetches data from a weather API (like OpenWeatherMap). Install dependencies first inside Replit’s shell:

npm install express node-fetch

Then write your Node server:

import express from "express";
import fetch from "node-fetch";

const app = express();

// Serve files from the "public" folder
app.use(express.static("public"));

// Weather API endpoint
app.get("/api/weather", async (req, res) => {
  const city = req.query.city;
  const apiKey = process.env.WEATHER_API_KEY; // Key stored in Secrets

  if (!city) {
    return res.status(400).json({ error: "City is required" });
  }

  try {
    // Fetch from OpenWeatherMap
    const response = await fetch(
      `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`
    );
    const data = await response.json();
    res.json(data);
  } catch (error) {
    res.status(500).json({ error: "Failed to fetch weather data" });
  }
});

app.listen(3000, () => console.log("Server running on port 3000"));

Insert this exact code into your index.js file. It runs on port 3000 by default and serves both your static files and a backend API route /api/weather. Replit will show a web preview button — clicking it opens your app.

 

Store Secrets Securely

 

In Replit, never put your API keys in plaintext. Click the padlock icon labeled “Secrets” in the left sidebar, create a new secret with the key name WEATHER_API_KEY and paste your actual weather API key as the value. Replit injects it into process.env when your code runs.

 

Frontend HTML & JavaScript

 

Create a new file public/index.html with a minimal interface and a text input for the city:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Weather App</title>
  <link rel="stylesheet" href="style.css" />
</head>
<body>
  <h1>Weather App</h1>
  <input id="cityInput" type="text" placeholder="Enter city name" />
  <button id="getWeatherBtn">Get Weather</button>
  <div id="result"></div>
  <script src="script.js"></script>
</body>
</html>

Then create public/script.js and add:

document.getElementById("getWeatherBtn").addEventListener("click", async () => {
  const city = document.getElementById("cityInput").value;
  const resultDiv = document.getElementById("result");

  resultDiv.innerHTML = "Loading...";

  try {
    const res = await fetch(`/api/weather?city=${city}`);
    const data = await res.json();

    if (data.error) {
      resultDiv.innerHTML = `<p>Error: ${data.error}</p>`;
      return;
    }

    resultDiv.innerHTML = `
      <h2>${data.name}</h2>
      <p>Temperature: ${data.main.temp} °C</p>
      <p>Weather: ${data.weather[0].description}</p>
    `;
  } catch (err) {
    resultDiv.innerHTML = "<p>Failed to fetch weather data.</p>";
  }
});

This frontend calls your Node.js backend instead of directly calling the weather API, which keeps your API key hidden on the server side — a key principle on Replit (and in web dev generally).

 

Good Replit Practices for Weather Apps

 

  • Use built‑in Replit HTTPS URL. Each Replit project runs on its own URL (e.g., https://yourusername.yourreplname.repl.co), so you can test the app live instantly.
  • Avoid long‑running loops or schedulers. Replit will pause your Repl if idle for too long unless you’re on a paid plan or use “Always On.” Instead, trigger updates via user requests or button clicks.
  • Keep dependencies minimal. Replit installs on a shared container, so smaller apps and fewer dependencies run faster and start quicker.
  • Use the Replit Shell and Console. For debugging, check your logs in the “Console” tab — it’s live‑streamed stdout from your server.
  • Version control with Git. Replit supports GitHub import/export in the left sidebar. Commit regularly so you can recover broken Repls easily.

 

Deployment Tips

 

  • Replit’s hosted URL is live as soon as you run the Repl.
  • If you need to share without letting people edit your code, click “Share” ➜ “Publish” or use the deployment feature which provides a stable copy.
  • Use “Always On” (from the “Deployments” tab) if you require the server to stay awake 24/7.

 

Common Pitfalls

 

  • Never expose keys in front‑end JS files. Anyone can see your static files.
  • Don’t treat Replit like a local dev environment. System-level package installs using apt or global modules often reset when the environment refreshes; prefer Node packages and Replit Secrets.
  • Don’t use relative localhost URLs. Always use the Replit-provided hosted URL if testing API calls from your local computer or external clients.
  • Be aware of memory and timeout limits. Keep responses lightweight and fast — a weather API call is perfect for this.

 

Following these steps, you’ll have a fully working weather app in Replit that securely fetches real weather data, keeps your API key safe, runs both backend and frontend in one Repl, and behaves reliably within Replit’s environment.

Client trust and success are our top priorities

When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.

Rapid Dev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with. They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

CPO, Praction - Arkady Sokolov

May 2, 2023

Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost. He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Co-Founder, Arc - Donald Muir

Dec 27, 2022

Rapid Dev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space. They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Co-CEO, Grantify - Mat Westergreen-Thorne

Oct 15, 2022

Rapid Dev is an excellent developer for no-code and low-code solutions.
We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Co-Founder, Church Real Estate Marketplace - Emmanuel Brown

May 1, 2024 

Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 
This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Production Manager, Media Production Company - Samantha Fekete

Sep 23, 2022