Service worker
A service worker is a JavaScript file the browser installs alongside a site and runs separately from the page, where it can intercept outgoing network requests and answer them from a local cache. It is what makes a web app load offline, and it only takes effect after a first visit made online.
A proxy that lives in the browser
A service worker is registered by the page, then runs in its own thread with no access to the DOM. Its main job is the fetch event: every request the page makes passes through it first, and the worker decides whether to answer from the cache, go to the network, or do both.
That decision is the caching strategy, and there are only a few common ones:
- Cache-first — serve the stored copy immediately, network only if nothing is stored. Fast and offline-proof, but can serve a stale page.
- Network-first — try the network, fall back to the cache when it fails. Fresh when online, still usable offline.
- Stale-while-revalidate — serve the cached copy instantly and quietly refresh it in the background. The usual choice for stylesheets, fonts and icons.
- Never cache — send it straight to the network. The right answer for anything live: database reads and writes, login, payments.
A published NorthernGo app is served a /sw.js that follows exactly this split, and deliberately keeps every database and auth call out of the cache so the app fails honestly rather than showing stale data.
The misconception: it does nothing on the first visit
A service worker cannot cache files it has never seen. The very first load has to happen with a connection — that request installs the worker and fills the cache. A user who opens your app for the first time in airplane mode gets nothing, no matter how good the caching strategy is.
Two more behaviours surprise people. A new service worker installs but stays waiting until every tab of the old one closes, so a deploy may not reach users on the next refresh unless the worker calls skipWaiting. And a worker only controls the scope it was served from: one served at the site root controls the whole origin, one served from a subfolder controls only that folder. Two workers cannot both own the same scope — the last one registered wins.
Frequently asked questions
Why does my service worker not update when I deploy?
A new version installs in the background but stays in a waiting state until every tab controlled by the old worker is closed — a refresh is not enough, since the old tab never fully goes away. Calling skipWaiting in the install handler, or closing all tabs, activates the new version.
Build it yourself
NorthernGo turns a plain-text description into a working web app with a database, login and a live URL. Local AI generation runs on your own GPU, is unlimited, and is free on every plan.