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 initwhen 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-offlineIf 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 initIt can generate:
offline.htmlmanifest.webmanifestgo-offline.config.tssw.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 initThe 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.htmlpublic/sw.jspublic/manifest.webmanifestgo-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
pwais 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, andmanifest.webmanifestinpublic/.
React
- Use
GoOfflineProviderat 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.jsis served from the correct public path- the browser supports service workers
- the page is served over
httpsorhttp://localhost swPathandscopematch where the file actually lives
Offline fallback is not showing
Check:
- the user has visited at least once while online
offline.htmlexists 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
versionin 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 verifyThen publish:
npm login
npm publish --access publicIf the package name is already taken, rename it before publishing.
Package Quality Checklist
- Replace placeholder repository URLs in
package.json - Replace
authorinpackage.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.