If you own an iPhone, your camera saves photos as HEIC files by default. Apple made this switch in iOS 11 to cut storage use roughly in half compared with JPEG. The format is technically superior in almost every way. Yet if you drag one of those files into a web app on Chrome or Firefox, you get a broken image icon or a blank canvas. The reason is not a missing feature. It is a deliberate architectural decision by every major browser vendor except Apple, rooted in patent law, container design, and codec licensing.
This article explains what HEIC actually is at the specification level, why it breaks on the web, and how ZeroCloudPDF converts HEIC files to PDF entirely inside the browser without uploading them to any server and without shipping a heavyweight WebAssembly decoder just for this one format.
What HEIC Actually Is
HEIC is not an image codec. It is a container profile. The underlying container is HEIF, the High Efficiency Image File Format, standardized as ISO/IEC 23008-12 by the Moving Picture Experts Group. HEIF itself is a special case of the ISO Base Media File Format, ISOBMFF, which is the same container specification that underpins MP4. If you understand MP4 boxes, you already understand 80 percent of HEIF structure.
Inside a HEIF file, still images are stored as items. Image sequences are stored as tracks. Each item or track references a codec. The HEIC profile specifically mandates that the image data inside is encoded with HEVC, also known as H.265, standardized in ISO/IEC 23008-2. This is the same codec used for 4K video compression, repurposed for still images.
A HEIC file begins with a FileTypeBox containing four character brand codes. The heic brand signals HEVC Main Profile or Main Still Picture profile. The heix brand signals Main 10 or format range extensions. These brands tell a decoder exactly what HEVC profile it needs to handle before it attempts to render a single macroblock.
Compared with JPEG, HEIC offers roughly 2x compression efficiency at equivalent visual quality. It supports 10 bit color depth, HDR, alpha transparency, and multiple images in a single file. It can store burst photos, depth maps for portrait mode, and even non destructive editing operations as derived images. In every measurable technical dimension, HEIC is a better format than JPEG.
Why Browsers Refuse to Decode It
The problem is not technical. It is legal and economic.
HEVC is patent encumbered by two separate licensing pools: MPEG LA and Access Advance. Any software that decodes HEVC must pay license fees to these pools. Apple builds that cost into its hardware margins, which is why Safari on macOS and iOS can decode HEIC natively. Google, Mozilla, and Microsoft made a different strategic choice. They invested in royalty free alternatives: VP9 for video, AV1 for next generation compression, and AVIF for still images.
As a result, Chrome, Firefox, Edge, and every Chromium derived browser treat HEIC as an unknown image type. Even on macOS, where the operating system can decode HEIC for Preview and Quick Look, Chrome does not pipe that OS level decoder into its web rendering engine. Firefox has tracked HEIF support as Bugzilla bug 1402293 since 2017. It remains open at priority P5 with no assigned engineer.
This means the web platform has no universal HEIC decoder. An <img> tag pointing to a .heic file renders in Safari and shows nothing everywhere else. The same applies to createImageBitmap(), drawImage(), and every other browser API that depends on the native image pipeline.
The Conversion Challenge
Converting HEIC to PDF requires decoding the HEVC bitstream into a raw bitmap, then re encoding that bitmap into a PDF compatible image format. In a server based architecture, this is trivial. You upload the file, the server runs libheif or ffmpeg, and returns a PDF. The file leaves your device, travels through HTTPS, sits on a server you do not control, and comes back.
For a privacy first tool, that upload is unacceptable. The alternative is to decode HEIC inside the browser. Several JavaScript libraries do this by compiling libheif to WebAssembly. The problem is size. A WASM HEIC decoder can weigh several megabytes compressed. For a tool that aims to load instantly and run on mobile connections, adding a multi megabyte binary for a single file format works against the performance the rest of the toolkit is built around.
The ZeroCloudPDF Approach: Use What the Browser Already Has
ZeroCloudPDF takes a different path for this one format. Instead of shipping a decoder, we use the decoder that already exists inside the browser.
On Safari for iOS and macOS, the WebKit engine includes a native HEIC decoder because Apple licenses HEVC across its entire stack. This means Safari can decode HEIC through the standard HTML5 Canvas API. When a user drops a .heic file into the upload area on an iPhone or a Mac running Safari, the browser reads the file, decodes the HEVC frames, and makes the raw pixel data available through createImageBitmap() or drawImage() on a canvas element.
The conversion pipeline is straightforward:
-
Detection: The upload handler inspects the file extension and MIME type. If it sees
.heicorimage/heic, it routes the file through the HEIC aware pipeline. -
Decoding: The file is passed to an
HTMLImageElementorcreateImageBitmap()call. On Safari, this triggers the native HEIC decoder. The result is a bitmap in memory. - Canvas rasterization: The decoded image is drawn onto an HTML5 canvas. At this stage, we can apply scaling, quality reduction, and dimension constraints. This is where compression happens.
- PDF generation: The canvas contents are passed to jsPDF, which encodes the image as JPEG inside the PDF container and writes the final document structure.
- Download: The resulting PDF is offered as a blob URL download. The entire flow stays inside the browser tab.
On Chrome or Firefox desktop, the native decoder does not exist. drawImage() with a HEIC source fails silently or produces a blank canvas. This is a known, disclosed limitation. We do not attempt to hide it with a massive WASM polyfill. The architecture is honest about what the platform can and cannot do.
Technical Architecture: How the Scripts Load
The HEIC to PDF tool is part of a larger image conversion pipeline. Here is how the architecture works at the script loading level.
Libraries do not load via static script tags on every page load. That approach would force every visitor to download jsPDF, pdf.js, and every other library regardless of which tool they actually need. Instead, each library is injected on demand, the moment a user actually starts a conversion that needs it, not before. A small set of loader functions in app.js handle this: calling a loader twice in flight returns the same promise rather than re-injecting the script.
For the image to PDF pipeline specifically, which is what HEIC to PDF runs on, only jsPDF is needed. There is no existing PDF to parse, so pdf.js never loads on this path. pdf.js is reserved for the tools that read an existing PDF, like Compress PDF, Merge PDF, and PDF to Image.
Most of these libraries are fetched from cdnjs.cloudflare.com. A couple of smaller, more specialized decoders, like the TIFF decoder used elsewhere in the image pipeline, load from jsDelivr instead. Firebase's own auth libraries load from Google's gstatic.com, separate from the PDF tooling entirely. There is no single CDN policy across the whole site; each library loads from wherever its own package is published, on demand, per tool.
The loading sequence is:
- The DOM renders and
app.jsloads early, since it owns the loader functions and the UI event handlers. - Nothing else loads yet. No PDF library is fetched just because a tool page opened.
- The moment the user triggers a conversion,
app.jscalls the specific loader that tool needs, and only that library is injected. -
typeofguards confirm the library is fully initialized before the conversion function runs against it.
This means the first visit to the homepage does not download a single PDF library. The libraries are cached only when the user actually opens a tool and runs a conversion. Once cached, they remain in the browser's standard HTTP cache. There is no service worker. There is no PWA. There is no engineered offline strategy. The airplane mode capability works because the libraries are already in the browser cache from a previous visit, and every tool runs as pure JavaScript with zero server contact.
Why Airplane Mode Works
After you have visited the site once and loaded a tool, the required scripts sit in your browser cache. If you disconnect WiFi, enable airplane mode, and return to the tool, the page still works. The HEIC file decodes locally. The canvas renders locally. The PDF generates locally. Nothing in that pipeline requires a network request.
This is not magic. It is the natural consequence of two architectural decisions:
- Every operation is pure JavaScript running in the browser.
- Libraries are loaded from CDN on demand and cached by the browser's standard HTTP cache mechanism.
There is no server round trip for file processing. There is no API call to generate the PDF. There is no cloud function. The only network dependency is the one-time library load, which persists in cache after that.
The All in One Flow
From the user perspective, the experience is simple. They select or drop a HEIC file into the upload box. The interface auto detects the format. On Safari, the conversion happens immediately. The image is decoded, compressed through canvas scaling, wrapped into a PDF by jsPDF, and presented for download. The user never leaves the page, never creates an account, and never uploads anything.
The compression happens during the canvas to PDF step. By controlling the canvas output dimensions and the JPEG quality parameter passed to jsPDF, the tool can reduce file size significantly while preserving readability. A 5 MB HEIC portrait photo might become a 400 KB PDF, suitable for email attachments and government portal uploads.
You can try the dedicated pipeline at zerocloudpdf.com/heic-to-pdf or use the general image conversion tool at zerocloudpdf.com/image-to-pdf, which handles HEIC along with JPG, PNG, and TIFF through the same client side architecture.
The Honest Tradeoff
This architecture makes a deliberate tradeoff. We sacrifice universal browser support for HEIC in exchange for zero bloat, zero upload, and zero patent licensing complexity. A Chrome user on Windows cannot convert HEIC through our tool because Chrome cannot decode HEIC. We do not attempt to fix this by shipping a multi megabyte WASM decoder. We disclose the limitation upfront.
For iPhone users, whose cameras save photos as HEIC by default, Safari on iOS handles the format natively. For Mac users, Safari on macOS does the same. The people who need this tool the most are the people who can use it without any polyfill at all.
Conclusion
HEIC is a technically excellent format trapped in a patent licensing structure that the open web refuses to adopt. Converting it to PDF inside the browser should not require uploading your photos to a remote server or downloading a multi megabyte decoder just for this one format. By leveraging the native decoding capabilities that Safari already provides, ZeroCloudPDF converts iPhone HEIC files to compressed PDFs using nothing more than the HTML5 Canvas API, jsPDF, and the browser's own cache.
The architecture is not magic. It is a careful alignment of what the platform can do, what the user actually needs, and what privacy demands.
Written by the ZeroCloudPDF team. ZeroCloudPDF is a privacy first PDF toolkit that processes every file directly in your browser. No upload required. No account needed.
Top comments (0)