One line of code decides it: strip a trailing .heic or .heif, add .jpg. Everything else in this article is what happens around that line — including three cases where the name on screen is not the name that lands on your disk.
a/b.heic saves as a_b.jpg
Short answer: the download name is your file's name with one trailing .heic or .heif removed and .jpg put on the end — case-insensitive, and only one extension is removed. IMG_1003.HEIC becomes IMG_1003.jpg. Nothing else about the name is touched: spaces, dots, parentheses, accents, emoji and digits all survive exactly as they were. Every conversion in the tables below was run on the live page today, and each one produced the usual 38,078-byte JPG at 700 × 476 from the same 41,465-byte photo.
Three cases where what you see is not what you get: a name of 244 characters or more downloads nothing at all while the page still shows a finished result; names containing characters your operating system refuses to store get rewritten (a/b.heic → a_b.jpg); and two photos with the same name silently overwrite each other in the download folder.
All of the following was measured today in Chrome 153 by actually downloading each file and reading the name that landed on disk.
The converter does not look at your photo's contents, its date, or anything inside the file. It takes the file name the browser hands it and runs one expression:
origName = file.name.replace(/\.(heic|heif|HEIC|HEIF)$/i, '')
and then uses origName + '.jpg' for both the download link and the line of text under the result. Three things follow from that expression, and all three showed up in the measurements:
i flag means case does not matter. .HEIC, .HeIc and .heic are all stripped.+ or g, so exactly one trailing extension is removed. photo.heic.heic becomes photo.heic.jpg — a JPG with .heic still in its name..heic and .heif are stripped. Any other extension is kept and .jpg is appended to it.Each of these was a real file handed to the page through its file picker. Every conversion succeeded, every output was 38,078 bytes, and in every case the name written to disk was exactly the name the page showed:
| File name in | Saved as | Note |
|---|---|---|
IMG_1003.HEIC | IMG_1003.jpg | upper-case extension stripped |
IMG_1004.heic | IMG_1004.jpg | — |
IMG_1005.heif | IMG_1005.jpg | .heif treated the same |
IMG_1006.HEIF | IMG_1006.jpg | — |
My Photo.heic | My Photo.jpg | space kept |
My Photo (1) - final.heic | My Photo (1) - final.jpg | brackets and dash kept |
photo.heic.heic | photo.heic.jpg | only the last one goes |
photo.jpg.heic | photo.jpg.jpg | double .jpg |
photo.heic.jpg | photo.heic.jpg.jpg | .heic is not trailing, so nothing is stripped |
noextension | noextension.jpg | no extension is fine |
photo.heicx | photo.heicx.jpg | near-miss is not stripped |
café_假期.heic | café_假期.jpg | non-Latin characters kept |
beach_🏖️.heic | beach_🏖️.jpg | emoji kept |
UPPER lower MiXeD.HeIc | UPPER lower MiXeD.jpg | mixed case stripped |
a.b.c.d.heic | a.b.c.d.jpg | many dots kept |
12345.heic | 12345.jpg | digits fine |
| a name of 185 characters | the same 185 characters minus .heic plus .jpg | long but fine |
Two of these are worth calling out because they look like bugs but are just the rule doing what it says. photo.jpg.heic comes out as photo.jpg.jpg — the .jpg was never going to be removed, so you get two. And photo.heic.jpg comes out as photo.heic.jpg.jpg: the .heic is not at the end, so it survives into your JPG's name.
The page sets the download name and prints it, but your browser has the final say about what it can actually write. Four kinds of name get changed, and the page has no idea — it still shows the unsanitised version:
| File name in | Page shows | Actually saved as |
|---|---|---|
a/b.heic | a/b.jpg | a_b.jpg |
a\b.heic | a\b.jpg | a_b.jpg |
a:b.heic | a:b.jpg | a_b.jpg |
a*b.heic | a*b.jpg | a_b.jpg |
a?b.heic | a?b.jpg | a_b.jpg |
a"b.heic | a"b.jpg | a_b.jpg |
a<b.heic | a<b.jpg | a_b.jpg |
a>b.heic | a>b.jpg | a_b.jpg |
a|b.heic | a|b.jpg | a_b.jpg |
con.heic | con.jpg | _con.jpg |
padded .heic | padded .jpg | _ padded .jpg |
.heic | .jpg | jpg.jpg |
..heic | ..jpg | jpg.jpg |
All nine separator and punctuation cases collapse to the same a_b.jpg. A reserved device name gains a leading underscore. Leading spaces become an underscore. And a file whose whole name is the extension produces a JPG called jpg.jpg — the name the page shows (.jpg) is not what lands.
Which of these were real files: the leading-spaces row and the .heic row came from real files on disk. The other eleven could not: this machine refuses to store / \ : * ? " < > | in a file name, and I put con.heic and ..heic through the same route for consistency. For those eleven I built a File object with that exact name inside the browser and dispatched the page's own drop event. The page's handler ran normally and the conversion was real, but the file did not arrive through the operating system's file picker — so what I measured is the page's naming, plus the browser's own saving rule, not a real file selection.
This is the one that can actually lose your photo, because the page gives you no warning. I downloaded increasingly long names and watched what happened:
| Length of the name that would be saved | Download folder path length | What landed on disk | Download reported |
|---|---|---|---|
| 243 characters | 63 | the file, 38,078 bytes | completed |
| 244 characters | 63 | nothing | canceled |
| 243 characters | 92 | the file, 38,078 bytes | completed |
| 244 characters | 92 | nothing | canceled |
| 245 characters | 92 | nothing | canceled |
| 246 characters | 92 | nothing | canceled |
The cut-off is the name, not the whole path: the same 243 lands and the same 244 fails whether the folder path is 63 or 92 characters, which puts the full path at 307 or 336 characters in the passing case. A longer folder does not reduce the name length that works. I did not determine whether the limit belongs to the browser or to the operating system, so I will not name a cause — only the boundary I measured.
What makes it dangerous is the silence. When the download was canceled, the page still showed a finished result — …jpg — 700×476 — 37 KB — with a live download button. Nothing on screen says the file was not saved.
I converted dup.heic, downloaded it, converted it again and downloaded again, then a third time. After each download the folder contained one file: dup.jpg, 38,078 bytes, every time. No dup (1).jpg appeared, and no prompt asked me anything — each download replaced the last.
Caveat, stated plainly: this was headless Chrome told to save downloads straight into a folder. A normal desktop browser with its usual download UI may number the second copy instead of replacing it. What I can say is that in the configuration I measured, the second photo silently destroyed the first.
.heic.heic or .jpg.heic first — you will otherwise get .heic.jpg or .jpg.jpg.No. Every conversion I ran today produced the same 38,078 bytes at 700 × 476, matching the repeat-conversion measurements. Only the name differs.
photo.heic.heic come out as photo.heic.jpg?Because the expression removes one trailing .heic or .heif, not all of them. It is a replace anchored to the end of the string with no repeat and no global flag.
Not from this page. The download name is always origName + '.jpg' and the output is always a JPEG — measured in the transparency tests, where the output has three components and no alpha.
Not for naming. It takes the name the browser gives it and nothing else. It does check the bytes to decide whether the photo is convertible at all — a JPEG renamed to .heic is rejected, as measured in the name-versus-bytes experiments.
Yes, if two conversions overlap. The name is kept in one shared place that each new file overwrites, so a result can carry the name of a photo that arrived after it. That is measured separately in the two-files-at-once tests.
I measured Windows and Chrome. Other operating systems refuse their own sets of characters and have their own reserved names, so the "saved as" column would differ. I did not measure them and will not guess.
Yes — once a photo has been converted, the download link is on the tab order and Enter downloads it. Getting the photo into the page by keyboard is a different matter; see the keyboard measurements.
Try it: open the converter, drop in a photo called photo.heic.heic, and watch the result line say photo.heic.jpg.
First published: 5 October 2026