Dev Tools

Building a PWA PDF Editor: Lessons from Shipping ILikePdf

By ILikePdf Team · July 10, 2026 · 5 min read

Why PWA for a PDF Editor

PDF processing is fundamentally a local operation — your browser reads a file, manipulates bytes, writes a result. There's no reason this should require a network connection. A Progressive Web App architecture makes the entire ILikePdf toolset installable and fully functional offline. This article covers the PWA decisions we made: service worker strategy, WebAssembly caching, manifest configuration, and the trade-offs in making a data-heavy application work as an installable app.

Service Worker Strategy: Cache-First for Assets, Network-Only for Nothing

ILikePdf is a static application. There are no API endpoints to fetch, no server-side rendering, no dynamic content. Every byte needed to run the tools — HTML pages, JavaScript bundles, CSS, fonts, and the critical WebAssembly modules — ships as static assets. This makes the caching strategy straightforward: cache everything on install, serve from cache on every request, and never fall back to the network.

self.addEventListener('install', event => {
event.waitUntil(
caches.open('ilikepdf-v1').then(cache =>
cache.addAll([
'/',
'/index.html',
'/compress-pdf.html',
'/merge-pdf.html',
'/split-pdf.html',
'/assets/js/lib/wasm/ghostscript.wasm',
'/assets/js/lib/wasm/ghostscript.js',
'/assets/css/main.css',
'/manifest.json',
])
)
);
});

self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(cached => cached || fetch(event.request))
);
});

The critical insight: by precaching the WASM modules during installation, we guarantee the tools are available offline without any additional lazy-loading logic. The trade-off is a larger initial download — about 8 MB for the Ghostscript WASM binary. We handle this by showing a clear installation progress indicator and deferring the service worker activation until after the user's first interaction.

Caching WebAssembly Modules

WASM modules present a unique caching challenge. They are large binary files that the browser compiles before execution. If we cache them via the standard Cache API, the browser must re-compile them on each page load. We experimented with two approaches. The first was compilation caching via `WebAssembly.compileStreaming()` combined with the Cache API — we store the compiled module in IndexedDB as a `WebAssembly.Module` object. The second was simple binary caching with streaming compilation on each load.

We chose the latter for ILikePdf. IndexedDB serialization of compiled modules has inconsistent performance across browsers and is slower than re-compiling from a local cache on most modern hardware. The M1 Mac compiles the 8 MB Ghostscript WASM in under 200 ms. On mobile, it takes roughly 500 ms — acceptable when the alternative is waiting for a server upload.

Manifest Configuration for Installability

The web manifest must meet specific criteria for the browser to offer installation. Our manifest includes all required fields plus several that improve the installable experience:

{
"name": "ILikePdf — Free PDF Tools",
"short_name": "ILikePdf",
"description": "Free online PDF tools — merge, split, compress, edit. No upload, no sign-up.",
"start_url": "/",
"display": "standalone",
"display_override": ["window-controls-overlay"],
"background_color": "#0f0f0f",
"theme_color": "#3b82f6",
"icons": [
{ "src": "/assets/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/assets/icons/icon-512.png", "sizes": "512x512", "type": "image/png" },
{ "src": "/assets/icons/icon-512-maskable.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
]
}

Key decisions: we set `display: standalone` for a native-like chrome-less experience. The `window-controls-overlay` display override enables the title bar area customization on desktop PWA installs. We include a maskable icon for Android adaptive icon support.

Offline First: The Technical Flow

When a user visits ILikePdf for the first time, the page loads, registers the service worker, and begins precaching. The user can start using tools immediately — without installation — because the page itself is functional. When the service worker finishes installing, it triggers a `waiting` state. We listen for this and prompt the user to install the PWA if they haven't already.

Once installed and the service worker is active, every subsequent page load serves from the cache. The user can enable airplane mode and process PDFs normally. All 46+ tools work offline because none of them require server communication. The only feature that degrades is analytics — we defer non-critical analytics events to IndexedDB and flush them when connectivity returns.

Lessons Learned

Key takeaway: A well-architected PWA makes the distinction between "website" and "app" disappear. ILikePdf users get the zero-friction access of a web search combined with the offline reliability and privacy of a native application.