9 September 2026
How it works
Drop a file, and the browser reads it into memory. Nothing is sent anywhere, ever.
Not before this step, not during it, not after — this site is a static export (next.config.ts: output: "export"), so there is no server for an upload to reach even if one were attempted.
A Web Worker loads the WebAssembly build for that format. So the tab stays responsive.
Dropping a .heic photo, for instance, loads libheif-js's wasm-bundle, and the decode and re-encode both happen off the page's main thread, however large the file is.
Very large files use the file system, not memory alone. convrtr deletes its own scratch files when done.
The scratch bytes go to the browser's Origin Private File System, and are deleted the moment a conversion finishes; any left behind by a crashed or force-quit tab are swept the next time the app loads (src/components/ServiceWorkerRegistration.tsx).
The finished file comes back as a download. Never uploaded, because nothing here can.
The finished file is handed back as a download from the same tab — never uploaded, because nothing here is capable of uploading it.
A generated service worker precaches the app shell. Offline is additive, not required.
scripts/generate-sw.mjs generates it, and after a first visit the tools keep working with the network switched off. Every conversion already works without that, though.
Docked Side Panel and right-click extraction. Manifest V3 integration without host permissions.
The convrtr Chrome Extension packages this exact WebAssembly pipeline into Chrome's native Side Panel. Users can drag files into the dock, convert images via right-click context menus, or capture visible viewports with Command+Shift+S. Full details live at /extension.
None of this is asserted only in prose. e2e/network-guard.ts checks every request.
It watches while the running page converts a real file, and fails the build if a single request carries file bytes off the device.