Privacy

Your images never leave the browser

Your images are processed locally in your browser. We do not upload or store your product photos on our servers. This page explains how that works and how it was verified.

The pipeline, step by step

  1. Read. The file input or drop event hands the page a File object. That is a handle to bytes on your disk, not a copy on a server.
  2. Decode. createImageBitmap(file) turns those bytes into an in-memory bitmap, honouring EXIF orientation.
  3. Render. The bitmap is drawn to an OffscreenCanvas inside a Web Worker, cropped and scaled to the target size.
  4. Encode. convertToBlob() produces a new Blob in the target format. The Blob lives in page memory.
  5. Package. JSZip assembles the Blobs into a ZIP and the browser saves it via a blob: URL.

At no point does a network request carry image bytes. The worker receives the File through structured clone, which is an in-process transfer.

What the network actually sees

The audit for this build recorded the requests below during a full run: upload four images, select three marketplaces, prepare the batch, download the ZIP. The results are reproducible with npm test, which includes a spec that fails if any request carries image data.

RequestWhenContains image data?
HTML documentPage loadNo
JS / CSS / worker chunksPage load and first processNo
favicon.svgPage loadNo

There are no requests to third-party origins, no font CDN, no analytics beacon and no image-processing API. Everything the app needs is served from the same origin as the page.

What is stored, and for how long

  • In memory: the uploaded files, their decoded dimensions, and the rendered output Blobs. Freed when you close the tab.
  • In localStorage: nothing. The billing flow would store one key, mit.plan, containing only the plan name — payments are not connected, so this build never writes it. Verified by the test suite, which asserts localStorage is empty after a full upload-and-export run.
  • On disk: only the ZIP you explicitly download.

The Clear all button releases every object URL immediately, so decoded pixels become eligible for garbage collection without waiting for a page unload.

Limits of this promise

Your hosting provider still sees ordinary HTTP requests: the page URL, your IP address and a user agent, like any website. That is not image data. If you add analytics or a CDN that logs request bodies later, this page must be updated — the guarantee is about the code in this repository, and the test suite is what keeps it honest.

Rules and audit reviewed 2026-11-03.

Questions

Do you upload my images?

No. Files are read through the browser File API, decoded with createImageBitmap, drawn to an OffscreenCanvas and re-encoded with convertToBlob. There is no upload endpoint in the application code.

Do you use analytics?

Not in this build. There is no analytics script, no session recorder and no error-reporting SDK. If that changes, it will be listed on this page with the exact vendor and what is sent.

What is stored on my device?

Nothing in this build. The billing flow would write a single key, mit.plan, holding only the plan name — but payments are not connected, so nothing is ever written. No filenames, no image data and no identifiers are persisted anywhere.

What happens when I close the tab?

Everything in memory is released by the browser. Object URLs are revoked, decoded bitmaps are closed, and nothing is written to IndexedDB, the Cache API or the file system.

Is the ZIP built on a server?

No. JSZip runs in the page and assembles the archive from Blobs that already exist in memory. The download is a blob: URL the browser writes to your disk.