How we convert
Transparency is the point of this site, so here is exactly what runs when you convert a photo. All of it executes in your browser; none of it sends your files anywhere.
Decoding: reading your photo
Wherever possible we use the browser's own decoder through the createImageBitmap API, which handles JPG, PNG, WebP, GIF, BMP and AVIF in every modern browser, and HEIC natively on Safari 17 and newer. When the browser cannot decode HEIC (Chrome, Firefox, Edge), we load a WebAssembly build of libheif, the open-source HEIF reference library, via the heic-decode package. The file's real format is detected from its first bytes, not its extension, so mislabeled files convert correctly.
Encoding: writing the output
JPG and PNG are encoded by the browser's canvas engine, with EXIF orientation applied first and transparency flattened to white for JPG. WebP uses the canvas encoder on Chrome, Firefox and Edge; Safari cannot encode WebP natively, so there we load a WebAssembly build of Google's libwebp (via jSquash). PDFs are assembled by jsPDF with the photo embedded as high-quality JPEG. Batch downloads are packaged by client-zip, which streams the archive without holding it all in memory.
Performance and memory
All decoding and encoding runs in a Web Worker, keeping the page responsive during large batches. On iPhones and iPads we process one photo at a time and recycle a single canvas, because iOS Safari caps total canvas memory; desktop browsers process up to four photos in parallel. Codec engines load lazily per conversion type and are cached by the browser, so the first conversion of a session pays a one-time download of at most a few megabytes and later ones start instantly.
Limits we will not pretend away
In-browser conversion is bounded by your device's memory: photos beyond roughly 100 megapixels may fail on phones. HEIC is supported as input only, because encoding HEIC requires HEVC patent licenses that make it impractical for free tools; no honest browser-based converter offers HEIC output. Animated formats currently convert their first frame. When we cannot convert something, the tool says so instead of silently uploading your file to a server, which is a line we do not cross.