Svelte Weather App

Demo project, showing the use of Svelte, TypeScript, and Express to build a weather forecast web app, powered by the AccuWeather API

What Is This?

This is a demo full-stack web application, which uses the AccuWeather API to power a multi-day forecast, with selectable location.

It uses Svelte, TypeScript, HTML, CSS, and other web technologies.

Configuration

There are a few values that are configurable for the backend and frontend.

Configuration for the backend can be done through either:

  • Setting the values via environmental variables
    • Example (Windows): set port=3002 && npm run serve
  • Copying /backend/.env.example.json to /backend/.env.json and filling in the values

🚨 In order to run this app you MUST provide a valid value for accuWeatherKey (which should be your API key), through either of the above methods.

For the full list of values you can configure for the backend, refer to the example .env.json file.

For the front-end, the only real configuration value is BACKEND_BASE, which can be used to decouple the serving of the API from the static files (see "Static Serving" section for details).

Running

Although you can cd to either /backend or /frontend and run each part of the app individually from its directory, all commands are exposed through the root package.json of this project for convenience.

From the root directory, here is a sample workflow for if you just cloned this repository:

  1. npm install:
    • Installs all shared dependencies, and then for each part of the app separately (through postinstall hook)
  2. Now that dependencies are installed, you can pick how to run or work on the app:
    • npm run dev
      • This runs both parts in dev mode, and watches for changes across the entire codebase and reloads if it sees any
    • npm run build
      • Builds both the frontend and backend. For Svelte, this means producing an optimized static HTML / JS / CSS output for hosting. For the backend, this means transpiling TypeScript to JS.
    • npm run serve
      • This serves both the server (internal API) and frontend.
      • Important: Having run npm run build is a pre-requisite to this command - serve is expecting that there is already build output ready to serve or execute.
      • Alternatively, you can run npm run start, which runs build and then serve
      • Reminder: The API requires a valid AccuWeather API Key to run, passed via accuWeatherKey. See "Configuration" for details.

Many commands also have optional suffixes if you don't want to work on both parts of the app at the same time. For example, you can use npm run dev:backend instead of npm run dev, if you just want to work on the API without touching the frontend.

Design Decisions

This is a mono-repo, which contains both the frontend, backend, and commands to run both.

  • Front-end is built with Svelte, TypeScript, and lots of HTML and CSS.
    • Vite is used for tooling; bundling, local HMR, production builds, etc.
    • The Halfmoon CSS Framework is used, but mostly for some utility classes and default styling
    • CSS variables are used liberally to make theming and tweaking easier
  • Back-end is using NodeJS, Express, and TypeScript
    • Since I don't need much in the way of a backend for this (mostly just proxying AccuWeather requests and static file serving), I kept things simple. For a more robust application, I would probably pick and use a full-fledged NodeJS framework, like NestJS or Hapi.
    • If I knew that this app was never going to be scaled beyond what it currently is, I would strongly consider serverless as a contender - the entire back-end could realistically be built out as one or two functions (and deployed on something like Netlify Functions, AWS Lambda, or GCP Cloud Functions).
    • There is some basic CSRF protection built-in, backed by cookies
  • There are some TypeScript types that are shared between the two parts
  • Some of the "extra" scripts in package.json are specific to DigitalOcean deployment settings

Static Serving

By default, this project will serve both the API and the frontend from the same Express server. However, I also made it configurable so that you can decouple them easily.

To decouple, before running build:frontend, set an environmental variable for BACKEND_BASE to point to the hosted Express endpoint. Then run build:frontend, and after it finishes, you can now take the optimized /dist and serve anywhere that lets you serve static files; Netlify, various CDNs, shared hosting, etc.

Known Limitations

The "automatic location" feature, based on IP address, uses AccuWeather's IP-to-geolocation service, which doesn't always return the most accurate results. To counter this, users are asked whether or not the "guessed" location is good enough for them, or if they would like to manually select a location, before forecasting data is fetched.

Demos:

Responsive

Multiple Display Modes

If I had more time...

If I had more time to work on this, here are the things I would focus on as top priority:

  • Localization
  • Tests!
  • Client-side caching of certain values (such as last location used)
    • Also pushing to browser location history and setting / restoring via query string for shareable URLs.
  • Server-side caching, to the extent that makes sense
    • For example, per location forecasts could be cached for a short duration. Although a small tweak, if this was scaled up to serve millions of users, a tweak like that could avoid thousands of duplicate requests for popular zip codes.
  • Get better graphical assets (such as the weather icons)

Top categories

svelte logo

Need a Svelte website built?

Hire a professional Svelte developer today.
Loading Svelte Themes