JSPM

go-offline

0.1.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 3
  • Score
    100M100P100Q71527F
  • License MIT

The easiest way to make your website work offline.

Package Exports

  • go-offline
  • go-offline/package.json

Readme

go-offline

The easiest way to make your website work offline.

go-offline is a production-ready npm package that helps developers add offline support to websites and frontend apps without hand-rolling service workers from scratch. It combines a small runtime API with an optional CLI so setup can stay simple without pretending browser code can generate project files by magic.

Why go-offline

  • Add offline support with a single import.
  • Use a first-class React provider and hooks when you want a React-native DX.
  • Keep service worker complexity behind sensible defaults.
  • Generate starter files with npx go-offline init when a project needs them.
  • Stay framework-friendly across React, Vite, vanilla JS, PHP, Laravel, and static sites.

What problem it solves

Most teams want offline support, fallback pages, and PWA basics, but do not want to manually build:

  • service worker registration
  • caching strategies
  • offline fallback handling
  • update detection
  • install prompt plumbing

go-offline gives you a lightweight v1 path that is technically honest:

  • runtime code handles browser-side setup
  • the CLI generates the files a runtime package cannot create

Installation

npm install go-offline

If you want TypeScript, React hooks, and the CLI in the same package, that is already included.

Quick Start

Universal usage

import { setupOffline } from "go-offline";

void setupOffline();

React usage

import { GoOfflineProvider } from "go-offline";

function App() {
  return (
    <GoOfflineProvider>
      <YourApp />
    </GoOfflineProvider>
  );
}

export default App;

Configured usage

import { setupOffline } from "go-offline";

void setupOffline({
  offlinePage: "/offline.html",
  pwa: true,
  debug: true,
  runtimeCaching: {
    pages: "network-first",
    images: "cache-first",
    api: "stale-while-revalidate",
    assets: "stale-while-revalidate"
  }
});

How It Works

go-offline has two parts:

Runtime

Use this inside your app code.

It handles:

  • service worker registration
  • online/offline detection
  • update lifecycle hooks
  • React provider/hooks
  • install prompt support
  • config normalization

CLI

Use this when you want starter files.

npx go-offline init

It can generate:

  • offline.html
  • manifest.webmanifest
  • go-offline.config.ts
  • sw.js

React Usage

Provider

import { GoOfflineProvider } from "go-offline";

export function App() {
  return (
    <GoOfflineProvider
      config={{
        offlinePage: "/offline.html",
        pwa: true,
        debug: true
      }}
    >
      <YourApp />
    </GoOfflineProvider>
  );
}

useOfflineStatus()

import { useOfflineStatus } from "go-offline";

function StatusBadge() {
  const { isOnline, isOffline } = useOfflineStatus();

  return <span>{isOffline ? "Offline" : "Online"}</span>;
}

usePWAInstall()

import { usePWAInstall } from "go-offline";

function InstallButton() {
  const { isInstallable, promptInstall } = usePWAInstall();

  if (!isInstallable) {
    return null;
  }

  return <button onClick={() => void promptInstall()}>Install app</button>;
}

useGoOffline()

import { useGoOffline } from "go-offline";

function Controls() {
  const { isOffline, update, promptInstall, isInstallable } = useGoOffline();

  return (
    <>
      <p>{isOffline ? "You are offline" : "You are online"}</p>
      <button onClick={() => void update()}>Check for update</button>
      {isInstallable ? <button onClick={() => void promptInstall()}>Install</button> : null}
    </>
  );
}

CLI Usage

Run:

npx go-offline init

The CLI asks a few beginner-friendly questions and generates starter files in your public web root. The generated sw.js is a working service worker starter, not a fake placeholder.

Recommended generated files:

  • public/offline.html
  • public/sw.js
  • public/manifest.webmanifest
  • go-offline.config.ts

Public API

setupOffline(config?)
registerServiceWorker(config?)
defineOfflineConfig(config)

GoOfflineProvider
useOfflineStatus()
usePWAInstall()
useGoOffline()

setupOffline(config?)

Registers the service worker, sets up connectivity tracking, and enables install prompt support when pwa is enabled.

Returns a controller with:

  • isOnline()
  • getRegistration()
  • update()
  • unregister()
  • destroy()

registerServiceWorker(config?)

Lower-level service worker registration helper. Use this if you want registration behavior without the full setupOffline() runtime controller.

defineOfflineConfig(config)

Type-safe helper for config files and editor autocomplete.

Config Reference

type CacheStrategy =
  | "cache-first"
  | "network-first"
  | "stale-while-revalidate"
  | "network-only"
  | "cache-only";

interface GoOfflineConfig {
  enabled?: boolean;
  debug?: boolean;
  swPath?: string;
  scope?: string;
  version?: string;
  offlinePage?: string;
  offlineImage?: string;
  precache?: string[];
  pwa?: boolean | {
    name?: string;
    shortName?: string;
    description?: string;
    themeColor?: string;
    backgroundColor?: string;
    display?: "standalone" | "fullscreen" | "minimal-ui" | "browser";
    startUrl?: string;
    icons?: Array<{
      src: string;
      sizes: string;
      type: string;
      purpose?: string;
    }>;
  };
  runtimeCaching?: {
    pages?: CacheStrategy;
    images?: CacheStrategy;
    api?: CacheStrategy;
    assets?: CacheStrategy;
  };
  callbacks?: {
    onReady?: (registration: ServiceWorkerRegistration) => void;
    onInstalled?: (registration: ServiceWorkerRegistration) => void;
    onUpdateAvailable?: (registration: ServiceWorkerRegistration) => void;
    onOffline?: () => void;
    onOnline?: () => void;
    onError?: (error: unknown) => void;
  };
}

Default behavior

Default runtime caching:

  • pages: "network-first"
  • images: "cache-first"
  • api: "network-first"
  • assets: "stale-while-revalidate"

Default generated paths:

  • swPath: "/sw.js"
  • offlinePage: "/offline.html"

Automatic vs Configurable

Automatic

  • browser support checks
  • service worker registration attempts
  • online/offline event listeners
  • default cache naming and versioning
  • default fallback HTML response if no custom offline page is cached
  • install prompt tracking when pwa is enabled

Configurable

  • service worker path and scope
  • fallback page path
  • offline image path
  • explicit precache entries
  • runtime caching strategies
  • cache version
  • PWA metadata
  • lifecycle callbacks
  • debug logging

Examples

The repo includes starter examples for:

  • React app
  • Vite app
  • plain HTML site
  • vanilla JS site
  • PHP website
  • Laravel public frontend

See examples/react-app, examples/vite-app, examples/plain-html, examples/vanilla-js, examples/php-site, and examples/laravel-public.

Project Setup Tips

Vite

  • Import setupOffline() in your main client entry.
  • Keep sw.js, offline.html, and manifest.webmanifest in public/.

React

  • Use GoOfflineProvider at the app root if you want hooks and shared state.
  • Use setupOffline() directly if you want a lighter integration.

PHP or Laravel

  • Put generated static files inside the public web root.
  • Register the runtime from your frontend bundle, not from server templates directly.

Troubleshooting

The service worker does not register

Check:

  • sw.js is served from the correct public path
  • the browser supports service workers
  • the page is served over https or http://localhost
  • swPath and scope match where the file actually lives

Offline fallback is not showing

Check:

  • the user has visited at least once while online
  • offline.html exists and is reachable
  • the service worker has been installed
  • the request is a navigation/document request

PWA install prompt never appears

That can be normal. Install prompts are browser-dependent and may require:

  • HTTPS
  • a valid manifest
  • icons
  • engagement heuristics
  • a supported browser

Development feels stale

Service workers can cache old files aggressively during local development. If needed:

  • unregister the service worker in DevTools
  • clear site storage
  • bump version in config when testing cache changes

Limitations

  • A user cannot use the app offline before the service worker has been installed once online.
  • A runtime package cannot create project files by itself, which is why the CLI exists.
  • Automatic asset discovery across every framework is out of scope for v1.
  • API caching is configurable, but should be used carefully for dynamic or authenticated data.
  • Cross-origin assets may not cache reliably depending on response headers and browser behavior.

Roadmap

Planned future directions:

  • route-aware caching rules
  • update notification helpers
  • cache expiration controls
  • offline form queue support
  • background sync helpers
  • IndexedDB utilities
  • plugin architecture
  • framework-specific adapters

Publish Instructions

Before publishing:

npm install
npm run typecheck
npm run build
npm run verify

Then publish:

npm login
npm publish --access public

If the package name is already taken, rename it before publishing.

Package Quality Checklist

  • Replace placeholder repository URLs in package.json
  • Replace author in package.json
  • Replace the copyright holder in LICENSE
  • Confirm generated examples match your final docs
  • Test the CLI in a real sample app before first public release

License

MIT

For open-source adoption, MIT is the right default for this package category.