SwoffSwoff

Ecosystem Compatibility

Framework, backend, and rendering strategy compatibility.

Swoff operates at the fetch event + Service Worker layer — below the application and data-fetching layers. This makes it compatible with any web stack regardless of backend language, frontend framework, or rendering strategy.

The only framework-specific surface is view adapters (React hooks, Vue composables, future Svelte). These are optional thin wrappers over postMessage to the SW. The core caching, offline, invalidation, and auth work without them.

Compatible with everything

CategoryExamplesConfig Hint
BackendPHP, Laravel, Django, Flask, Rails, ASP.NET, Go, Java, Nodenavigation.mode: "default"
HTML-over-wireHTMX, Turbo Hotwire, Unpoly, Livewirenavigation.mode: "ssr"
SSGAstro, VitePress, Hugo, 11ty, Jekyllnavigation.mode: "default", strategy cache-first
SPA frameworksReact, Vue, Svelte, Solid, Angular, Alpinenavigation.mode: "spa" (default)
Meta-frameworksNext.js, Remix, Nuxt, Quasar, SvelteKit, TanStack StartAuto-detected; navigation.mode: "ssr" + framework-specific ignoreQueryParams
RSC-basedNext.js App Routernavigation.mode: "ssr" + ignoreQueryParams: ["_rsc"] (auto-detected)
Edge / ServerlessCloudflare Workers, Deno Deploy, Vercel EdgeEdge runs on CDN, Swoff runs in browser — independent layers, no conflict
Islands / ResumabilityAstro islands, Qwik, MarkoSW runs in its own thread regardless of component hydration

No package.json required

Swoff needs Node.js only for the toolchain — the CLI (@swoff/cli) generates your files and the build script produces the final service worker. The generated output is plain JavaScript. The SW filename is always sw.js (no version appended), and version mode defaults to "hash" which needs no package.json. Your production app does not need Node.js, npm, or a package.json.

Workflow for any project

# 1. Generate config (no package.json needed)
npx @swoff/cli init --framework no-bundler

# 2. Generate all files
npx @swoff/cli generate

# 3. Build the final service worker
node swoff/sw/generator.mjs

# 4. Include in your HTML
<script src="/swoff/client-injector.bundle.js"></script>

The generated files in swoff/ are static — serve them however you serve your other assets.

CI / Docker integration

For non-JS projects, add the Swoff generator to your Makefile or CI pipeline:

# Makefile
build:
	composer install            # or pip install, go build, bundle install
	npx @swoff/cli generate
	node swoff/sw/generator.mjs  # final SW output
	# swoffPath in config controls where files land; no copy needed

In Docker, Node.js is only needed in the build stage:

# Multi-stage Docker build
FROM node:20-alpine AS swoff-build
WORKDIR /app
RUN npx @swoff/cli init --framework no-bundler \&\& npx @swoff/cli generate
RUN node swoff/sw/generator.mjs

FROM php:8.2-apache AS runtime
COPY --from=swoff-build /app/swoff /var/www/html/swoff
COPY --from=swoff-build /app/swoff.config.json /var/www/html/
# Your PHP app code, composer install, etc.
# swoffPath in config controls where files land inside the runtime image

The final image contains only static JS files — no Node.js runtime required in production.

Per-ecosystem examples

StackHow to serve generated filesGuide
No-bundler (Go, Laravel, Django, Flask, Rails, PHP, plain HTML/JS)Serve from your public/static directory and include <script src="/swoff/client-injector.bundle.js">No-bundler guide
HTMXInclude <script> tag, control via hx-headersHTMX guide
Plain HTML / StaticServe from document root and reference with a <script> tagVanilla guide

On this page