output=format:jpg,quality:85/
# Or convert on every upload
storeTo: { workflows: ['YOUR_WORKFLOW_ID'] }
What HEIC Is
HEIC is the High Efficiency Image Container, an image encoded with HEVC, or H.265, and held in a HEIF container.
HEIF sits in the ISO Base Media File Format family, the same family as MP4, so a single HEIC file holds more than one simple image. It carries 16 bit colour, transparency, depth maps and the image sequences behind Live Photos and burst captures.
Apple made it the default photo format in iOS 11 and macOS High Sierra, and Android has supported HEIF since Android 9. Apple’s support documentation gives HEIF and HEVC as offering better compression than JPEG and H.264 at similar visual quality.
The container and the codec have different licensing. HEIF itself is royalty free, and the HEVC codec inside it carries patent licensing requirements, which is where browser support parts company with it.
What JPG Gives You Instead
JPEG trades features for reach. It carries no transparency, no more than 8 bits a channel and no image sequences, and at similar visual quality a JPEG file can be larger than the HEIC it came from.
What it has is compatibility, which is the one thing a delivery format cannot compromise on. WebP and AVIF compress better and are now widely supported, though neither is as universal as JPEG, so a practical pipeline keeps JPG as the baseline and serves the newer formats where the browser accepts them.
Usage share for HEIF and HEIC from caniuse.com as of 2026. JPEG is standardised separately as ISO/IEC 10918-1 and ITU-T T.81, lossy, 8 bit colour, and readable by effectively every browser and image library.
Where a HEIC File Stops Rendering
Displaying HEIC needs an HEVC decoder. Three layers of a typical stack are missing one, and each fails differently.
In the browser
Chrome, Firefox and Edge ship no HEVC decoder, so an img pointing at a HEIC file shows a broken image or offers a download. Safari 17 and later renders HEIC and HEIF natively on supported macOS and iOS versions.
In server side image processing
Image libraries reach HEIC through extra packages such as libheif with an HEVC decoder. A default server image without them fails at thumbnail generation and at any other processing step.
On the operating system
Windows opens HEIC once the HEIF Image Extensions are installed alongside a separate HEVC Video Extensions package, which puts two dependencies in front of one photo.
Caniuse’s HEIF/HEIC table records the format as offering better compression than WebP, JPEG, PNG and GIF, and as complex and expensive to license. A W3C Breakouts Day 2026 session on HEIF support in browsers drew one of the event’s largest audiences and closed on discussion rather than adoption, and the Firefox feature request for HEIF support has been open since 2017.
Where in the Upload Path the Conversion Happens
Three points in the path can produce the JPG. They differ in who pays for the conversion and how often it runs.
Before the upload
The browser or the mobile app converts on the device. That ships an HEVC decoder in JavaScript or WebAssembly to every user, and the conversion depends on that code loading.
When the image is requested
The HEIC is stored as it arrived and converted on first request. The first reader pays the conversion cost, and the result caches for everyone after them.
When the image is uploaded
Conversion runs once inside the upload path. The HEIC stays as the master file, the JPG is generated a single time, and every later request reads a file that already exists.
Filestack covers the second and third of these directly. On the fly transformation puts the instruction in the CDN URL and caches the result. A Workflow runs the conversion when the file is uploaded and stores the JPG as its own file. A backend that wants to drive the conversion itself uses the SDK for the same processing task.
Three Ways to Convert HEIC With Filestack
All three run the same Processing Engine task. What changes is when the conversion happens and whether the JPG is stored.
GET https://cdn.filestackcontent.com/
# Convert AND store a new JPG file
GET https://cdn.filestackcontent.com/
# With app security enabled
GET https://cdn.filestackcontent.com/
# Deliver WebP where supported, JPG otherwise
GET https://cdn.filestackcontent.com/
// on every upload
import * as filestack from 'filestack-js';
const client = filestack.init('YOUR_API_KEY');
client.picker({
accept: ['image/*'], // includes image/heic, image/heif
storeTo: { workflows: ['YOUR_WORKFLOW_ID'] },
onFileUploadFinished: (file) => {
// file.handle, file.url, file.mimetype ('image/heic'), file.size
saveOriginalHandle(file.handle);
}
}).open();
// The same Workflow can be triggered with a direct SDK upload
client.upload(fileBlob, {}, { workflows: ['YOUR_WORKFLOW_ID'] });
const url = client.transform(handle, { output: { format: 'jpg' } });
// Chain the store task to save the converted file:
// output=format:jpg/store/HANDLE
// The response includes information about the new file,
// such as its handle, URL, size, and type.
All three work from the same handle the Picker or the Upload API produced, so a pipeline can start on the CDN URL and move to a Workflow without re-uploading the originals. Applications with security enabled allow convert, store and runWorkflow in the policy and signature.
One HEIC File Through the Pipeline
The file uploads, its metadata is read, the conversion runs on the fly and stores the JPG, and the result’s metadata is read again.
The original HEIC
The converted JPG
The original file stays unchanged. Only the format of the delivered file changes.
Conversion Approaches Side by Side
A decision guide rather than a ranking. Most pipelines end up using two of the three for different jobs.
| Client side, browser or app | Filestack CDN URL | Filestack Workflow | |
|---|---|---|---|
| Trigger | Before upload, on the device | First request for the JPG URL | Automatically on upload |
| Where it runs | The user's CPU, JS or WASM decoder | Filestack Processing Engine | Filestack Processing Engine |
| Consistency | Varies by browser and device | Same for every request | Same for every upload |
| Original preserved | Only if uploaded as well | Yes, the handle is unchanged | Yes, the original is kept |
| JPG persisted | Locally | Cached, not stored separately | Yes, through the store task |
| Latency | Slow on low end devices | First request converts, then cached | Asynchronous, result on a webhook |
| Setup | Ship a decoder library | Change the URL | Add a Workflow ID to storeTo |
| Best for | Offline first apps | One off derivatives | Repeatable automatic conversion |
Straight talk: an offline first app that has to produce a JPG with no network is the case client side conversion wins outright, and shipping the decoder is the price of that. Everything that reaches a server is cheaper to convert once, upstream.
Edge Cases in a HEIC to JPG Conversion
Four properties of HEIC that JPEG handles differently. Each is a setting decided once, in the Workflow or the URL template.
What happens to a Live Photo when it becomes a JPG?
A Live Photo HEIC holds a main still image and a motion sequence. Conversion extracts the primary still and delivers that as the JPG. The motion sequence stays in the original HEIC, since JPG carries a single image. The photo converts; the Live Photo experience lives in the master file.
Why does the converted JPG come out sideways?
iPhones record orientation in EXIF metadata rather than rotating the pixels. A client that reads EXIF orientation loosely then shows the image on its side. The Filestack Processing Engine handles this explicitly with rotate=deg:exif, which applies the recorded orientation during processing.
What happens to HDR and higher bit depth colour?
HEIC carries higher bit depth and HDR data, and a JPEG pipeline targets 8 bit output, so the extra colour information maps down into sRGB. Very bright highlights carry slightly less detail after conversion. That is the expected result of moving from HDR HEIC to standard JPEG.
Which JPEG quality value should the pipeline use?
The output task takes a quality value from 1 to 100, and quality:input carries the source setting through. Around 80 to 90 suits web delivery. The compress task reduces the file further where size matters more than the last of the detail.
Practices for a HEIC Upload Pipeline
Seven settings that keep every HEIC upload converting the same way, whichever device produced it.
What the Workflow Sends Back
The Workflow runs asynchronously, so the upload finishes before the JPG exists. Filestack posts the result to your endpoint when it is ready.
Large HEIC files ride the same multipart uploader, with 6 MB parts, 3 concurrent parts and up to 10 retries with exponential backoff. Intelligent Ingestion covers the unstable connections, which is the subject of chunked file uploads with resume support.
Read results for the new JPG handle and sources for the HEIC it came from. Failed deliveries retry after 5 minutes, 30 minutes and 12 hours, and workflow_status=job_id answers a direct poll.
"action": "fs.workflow",
"text": {
"workflow": "WORKFLOW_UUID",
"status": "Finished",
"sources": ["ORIGINAL_HEIC_HANDLE"],
"results": {
"output_1755500000000": {
"data": {
"filetype": "jpg",
"mimetype": "image/jpeg",
"handle": "NEW_JPG_HANDLE",
"size": 412884,
"url": "https://cdn.filestackcontent.com/
}
}
}
}
}
Frequently Asked Questions
How do I convert HEIC to JPG automatically on upload?
Create a Filestack Workflow with an output task set to jpg and a store task, then pass its ID through the Picker as storeTo.workflows or through the SDK as storeOptions.workflows. Every upload is converted and stored, and the new handle arrives on your webhook.
Why does my HEIC image not display in Chrome?
Chrome, Firefox and Edge ship no HEVC decoder, and HEIC images are HEVC encoded, so those browsers render nothing. Safari 17 and later supports HEIC and HEIF natively, including on iOS 17. Converting to JPG, WebP or AVIF covers every browser.
Can Filestack convert HEIC files?
Yes. The Filestack Processing Engine accepts HEIC and HEIF input and converts it with the output task, such as output=format:jpg or output=format:png. The conversion runs from a CDN URL, inside a Workflow, or through client.transform().
What is the Filestack URL to convert HEIC to JPG?
Request cdn.filestackcontent.com with output=format:jpg,quality:85 ahead of the handle. Adding /store/ before the handle persists the converted JPG as a new file. Applications with security enabled also carry security=p:POLICY,s:SIGNATURE on the request.
Does converting HEIC to JPG lose quality?
A little. JPEG is lossy and holds 8 bit colour, while HEIC can carry 10 bit, 16 bit and HDR data. At quality 85 to 95 the difference is hard to see on a typical web image. Keeping the HEIC preserves the original.
How do I handle Live Photos when converting?
A Live Photo HEIC holds a primary still image alongside an image sequence. Conversion extracts the primary still and delivers it as the JPG. The motion sequence stays in the original file, since JPG carries single images.
Is the HEIC conversion synchronous?
It depends on the approach. A CDN URL converts as part of the request and the result caches at the edge. A Workflow runs asynchronously, so the upload finishes first and the result arrives through the fs.workflow webhook or a workflow_status poll.
Should I convert HEIC to JPG or to WebP and AVIF?
JPG is the universal baseline, since browser support for it is effectively complete. WebP and AVIF go to the browsers that accept them. The Filestack auto_image task picks a supported encoding from the request, so one URL covers both.
Related Reading
The reference pages behind the tasks on this page, and the upload topic next to it.
Filestack Workflows
Conversion on ingest, task chaining, and the webhook that carries the new handle back.
Policy and signature
Signing every request, and allowing , and in the policy.
Chunked, resumable uploads
How the file arrives before the conversion runs, in parts that survive a dropped connection.