<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: swapfileio</title>
    <description>The latest articles on DEV Community by swapfileio (@swapfileio).</description>
    <link>https://dev.to/swapfileio</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3930090%2Fc2c456c2-5390-48ff-a845-9cf0e5dd1354.png</url>
      <title>DEV Community: swapfileio</title>
      <link>https://dev.to/swapfileio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/swapfileio"/>
    <language>en</language>
    <item>
      <title>Why Windows Still Can't Open HEIC Files in 2026 (And What Actually Works)</title>
      <dc:creator>swapfileio</dc:creator>
      <pubDate>Thu, 04 Jun 2026 14:31:26 +0000</pubDate>
      <link>https://dev.to/swapfileio/why-windows-still-cant-open-heic-files-in-2026-and-what-actually-works-5513</link>
      <guid>https://dev.to/swapfileio/why-windows-still-cant-open-heic-files-in-2026-and-what-actually-works-5513</guid>
      <description>&lt;p&gt;The scenario is familiar: someone takes a photo on an iPhone, sends it to you over email or WhatsApp. You try to open it on Windows — a warning appears: &lt;em&gt;"Codec required to open this HEIC file."&lt;/em&gt; You click it, Microsoft Store opens to "HEVC Video Extensions," and the price says &lt;strong&gt;$0.99&lt;/strong&gt;. They're asking you to pay just to view an image.&lt;/p&gt;

&lt;p&gt;It's 2026. HEIC is 9 years old (Apple introduced it in iOS 11 in 2017), and this problem is still here. It's not a coincidence — it's a structural choice. This article explains &lt;strong&gt;why it's still happening&lt;/strong&gt; and walks through &lt;strong&gt;5 solutions that actually work in 2026&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the actual problem?
&lt;/h2&gt;

&lt;p&gt;A "HEIC file" is really two technologies stacked together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HEIF&lt;/strong&gt; — High Efficiency Image File Format (container standard, developed by MPEG)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HEVC&lt;/strong&gt; — High Efficiency Video Coding, aka H.265 (the compression codec, also MPEG)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apple bundled these together and called it "HEIC." The HEIF container is a royalty-free open standard, but the HEVC codec is &lt;strong&gt;patent-encumbered&lt;/strong&gt; — any company that wants to use it has to pay royalties to MPEG LA. iPhone manufacturer (Apple) already pays. Windows manufacturer (Microsoft) wants the user to cover the cost.&lt;/p&gt;

&lt;p&gt;That's where the 99 cents come from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microsoft's awkward setup
&lt;/h2&gt;

&lt;p&gt;Microsoft Store has two separate extensions, and the split is deliberately confusing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;HEIF Image Extensions&lt;/strong&gt; — Free. Container support. But on its own, it can't display HEIC files because it has no HEVC decoder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HEVC Video Extensions&lt;/strong&gt; — $0.99. The decoder you actually need. The name is misleading; it's required for HEIC photos too.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There's also a third version, "HEVC Video Extensions (Device Manufacturer)," which is &lt;strong&gt;free&lt;/strong&gt; but only ships pre-installed by OEMs (Dell, HP, Lenovo, etc.). If you bought a new Dell with Windows 11 pre-installed, you probably already have it. If you have an older machine or a custom build, you don't. The same file opens for free on an OEM machine and costs $0.99 on your personal box.&lt;/p&gt;

&lt;p&gt;This is a freely-made choice. Microsoft has historically been reluctant to support Apple's image formats. We waited until 2024 for native AVIF in Windows. WebP support came through Chromium, not Microsoft. HEIC is the latest chapter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who's to blame?
&lt;/h2&gt;

&lt;p&gt;Short answer: &lt;strong&gt;all three parties get a share&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apple&lt;/strong&gt; never made HEIC a real standard. When they announced it in iOS 11, they called it "the new default for the camera," but didn't invest in interoperability. iCloud Photos automatically converts HEIC to JPG when displaying on non-Apple platforms — Apple themselves know HEIC is broken outside their ecosystem, they just choose not to engage with the problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Microsoft&lt;/strong&gt; owns one of the world's most popular desktop OSes and asks users to pay to open an image format. By 2026 UX standards, this is absurd. Even Linux distributions ship the same codec for free (the &lt;code&gt;libheif&lt;/code&gt; package).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MPEG LA&lt;/strong&gt; and the patent-pool structure underpin this whole mess. The royalty model is the polar opposite of where the open web is going — WebP and AVIF are BSD/MIT-licensed, royalty-free. They're winning for that reason.&lt;/p&gt;

&lt;p&gt;HEIC's share will gradually erode to AVIF (royalty-free + smaller). Apple has been testing AV1 codec under the "HEIC or High Efficiency" setting since iOS 18. The problem will solve itself — but not for today's user.&lt;/p&gt;

&lt;h2&gt;
  
  
  5 solutions that actually work in 2026
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Buy Microsoft HEVC Extension ($0.99) — the official path
&lt;/h3&gt;

&lt;p&gt;Official, permanent, system-wide. Get &lt;a href="https://apps.microsoft.com/detail/9nmzlz57r3t7" rel="noopener noreferrer"&gt;"HEVC Video Extensions" from Microsoft Store&lt;/a&gt;, install it, done. HEIC files open natively in Windows Photos. Pay once, works forever.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When not to:&lt;/strong&gt; You've seen 2 HEIC files in your life and want a free alternative — paying isn't worth it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Convert online — free, fast, private
&lt;/h3&gt;

&lt;p&gt;Got one HEIC to open? Don't bother installing anything. Convert online, download JPG, move on.&lt;/p&gt;

&lt;p&gt;The big online converters (Smallpdf, iLovePDF, ezgif) ship with Google Analytics, Facebook Pixel, and Hotjar trackers. If your HEIC happens to be a private moment (family photo, signed document), privacy starts to matter. The honest pitch for our own tool, &lt;a href="https://swapfile.io/en/tools/heic-to-jpg" rel="noopener noreferrer"&gt;SwapFile.io HEIC to JPG&lt;/a&gt;, is the inverse of that: files auto-deleted within 1 hour, Plausible analytics only (cookieless, 1 KB), no Google Analytics, no Facebook Pixel, no signup for files under 5 MB.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When not to:&lt;/strong&gt; Batch converting 50+ files — offline solution is faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. CopyTrans HEIC for Windows — free for individuals
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.copytrans.net/copytransheic/" rel="noopener noreferrer"&gt;CopyTrans HEIC&lt;/a&gt; is free for personal use and installs directly (not through Microsoft Store). It enables system-wide HEIC support — thumbnails show up in File Explorer, Photos opens HEIC natively, you can drag-and-drop into Office documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When not to:&lt;/strong&gt; Business use requires a license. Still, for one-off personal use, it's the lowest-friction offline option.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Change format on iPhone itself — the preventive fix
&lt;/h3&gt;

&lt;p&gt;The most sustainable solution: fix the source. On iPhone, go to &lt;strong&gt;Settings → Camera → Formats → "Most Compatible"&lt;/strong&gt;. From then on, all photos are saved as JPG.&lt;/p&gt;

&lt;p&gt;Trade-off: files are roughly &lt;strong&gt;2x larger&lt;/strong&gt;. Your iCloud quota and phone storage fill up faster. But if you're tired of dealing with HEIC problems, it's a worthwhile trade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When not to:&lt;/strong&gt; Using 4K Live Photos or Cinematic mode — some features depend on HEIC.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Open on macOS, export to JPG — if you have a Mac
&lt;/h3&gt;

&lt;p&gt;macOS has had native HEIC support since High Sierra (10.13). If you have a Mac: open the file → Preview → File → Export As → JPEG → save. Fast for one-offs, slow for batches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When not to:&lt;/strong&gt; No Mac, no solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which scenario, which solution?
&lt;/h2&gt;

&lt;p&gt;A practical decision table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Best Solution&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;we open 100+ HEIC files a year&lt;/td&gt;
&lt;td&gt;#1 — Microsoft HEVC Extension ($0.99, one-time)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Family photo arrived, just want to open + move on&lt;/td&gt;
&lt;td&gt;#2 — Convert online, download, forget&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;System-wide free solution&lt;/td&gt;
&lt;td&gt;#3 — CopyTrans HEIC (personal use)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Want to fix the source&lt;/td&gt;
&lt;td&gt;#4 — Switch iPhone to JPG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Have a Mac, quick one-off&lt;/td&gt;
&lt;td&gt;#5 — macOS Preview + Export&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Work computer, sensitive file&lt;/td&gt;
&lt;td&gt;#2 (privacy-first) or #1 (official codec)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can we preview HEIC files in Outlook?&lt;/strong&gt;&lt;br&gt;
On Windows with the HEVC Video Extension installed, the Outlook Preview pane shows HEIC automatically. Web Outlook (in a browser) can't — you'll still need to convert to JPG or download and open on your desktop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does WhatsApp auto-convert HEIC to JPG?&lt;/strong&gt;&lt;br&gt;
WhatsApp converts client-side because most of their recipients are on different platforms — Android, Windows web — and none of them have universal HEIC support. It's a real-world snapshot of how Apple's "HEIC works everywhere" claim plays out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it make sense to convert HEIC to AVIF instead of JPG?&lt;/strong&gt;&lt;br&gt;
AVIF is royalty-free, about 20% smaller than HEIC, and supported in 94% of modern browsers. If you're putting the file on the web, AVIF makes sense. If you're archiving, JPG is safer for universal compatibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will HEIC eventually go away?&lt;/strong&gt;&lt;br&gt;
Probably yes, but slowly. Apple has been testing AV1 codec since iOS 18. AVIF (royalty-free + more efficient) is on the rise. HEIC's peak was 2018-2024. By around 2030, most new content will likely be in AVIF — but solutions for years of accumulated HEIC files will still be needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The HEIC problem isn't technical; it's ecosystem politics. Three large companies (Apple, Microsoft, MPEG LA) have been arguing about "who licenses which codec" for years. In the meantime, millions of users have to browse the web to open a small file.&lt;/p&gt;

&lt;p&gt;The solution is actually simple: pick one of the 5 paths above. Whatever your scenario, in 2026 HEIC should no longer be a barrier that stops you.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://swapfile.io/en/blog/windows-heic-2026-solutions" rel="noopener noreferrer"&gt;SwapFile.io&lt;/a&gt;. SwapFile.io is a privacy-first image and PDF converter — files auto-delete in 1 hour, no Google Analytics, free for the first 6 months. Try it: &lt;a href="https://swapfile.io/en/tools/heic-to-jpg" rel="noopener noreferrer"&gt;swapfile.io/tools/heic-to-jpg&lt;/a&gt;. Feedback welcome.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>privacy</category>
      <category>windows</category>
    </item>
    <item>
      <title>How We Built a Privacy-First PDF Merger in 7 Hours: The Stack and the Lessons</title>
      <dc:creator>swapfileio</dc:creator>
      <pubDate>Sun, 24 May 2026 22:59:06 +0000</pubDate>
      <link>https://dev.to/swapfileio/i-built-a-privacy-first-pdf-merger-in-7-hours-heres-the-stack-and-the-lessons-41c8</link>
      <guid>https://dev.to/swapfileio/i-built-a-privacy-first-pdf-merger-in-7-hours-heres-the-stack-and-the-lessons-41c8</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Day 8 of building SwapFile.io (privacy-first image/PDF converter) in public. Yesterday we shipped a feature we needed ourselves: PDF Merge. Total time: ~7 hours from "do we have this?" to production. Stack: Go + Fiber + PostgreSQL + Next.js 16. The interesting bits are about what we didn't have to write.&lt;/p&gt;

&lt;p&gt;Live: &lt;a href="https://swapfile.io/en/tools/pdf-merge" rel="noopener noreferrer"&gt;swapfile.io/en/tools/pdf-merge&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Most online PDF mergers do something we didn't realize until we tested four of them: &lt;strong&gt;they rasterize your PDFs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You upload a contract with selectable text, signed and form-filled. You merge it with an addendum. You download the result. The output is... a stack of images. Text is no longer searchable. Form fields are flat pixels. Bookmarks gone. File size often triples.&lt;/p&gt;

&lt;p&gt;Smallpdf does this. iLovePDF does this. PDF24 does this in their default flow. The reason is the same for all three — they use server-side rendering tools that go through a raster pipeline because it's simpler and gives them more control over the output.&lt;/p&gt;

&lt;p&gt;we wanted the opposite: take what we uploaded, glue them together at the structural level, give us back exactly what went in. Searchable text. Embedded fonts. Bookmarks. Form fields. All intact.&lt;/p&gt;

&lt;h2&gt;
  
  
  The unsexy answer: pdfunite
&lt;/h2&gt;

&lt;p&gt;Poppler-utils ships with a binary called &lt;code&gt;pdfunite&lt;/code&gt;. It's been around for over a decade. It does exactly one thing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pdfunite in1.pdf in2.pdf in3.pdf out.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It doesn't rasterize. It doesn't recompress. It opens each input as a PDF object graph, appends pages in order, fixes up the cross-reference table, writes the result. Output is byte-for-byte equivalent to the inputs for text/fonts/images.&lt;/p&gt;

&lt;p&gt;Smallpdf could have used this. So could iLovePDF. They chose not to because their pipeline is built around server-rendered images for the preview/print path, and merging via pdfunite means having a second code path. For a solo founder, having one less code path is a feature, not a downside.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Go wrapper
&lt;/h2&gt;

&lt;p&gt;Bridging Go to pdfunite is 50 lines of stdlib subprocess code. Here's the core:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;PDFUnite&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;binary&lt;/span&gt;  &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewPDFUnite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;PDFUnite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;exec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LookPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"pdfunite"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ErrPDFUniteMissing&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;PDFUnite&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;PDFUnite&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inputPaths&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outPath&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;MergeResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputPaths&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"need at least 2 input files"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;inputPaths&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;cctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;exec&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CommandContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;stderr&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;
    &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stderr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;

    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"pdfunite failed: %v — %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;MergeResult&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;OutputPath&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;outPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;OutputSize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Since&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fail-fast at startup if the binary isn't in PATH. Hard timeout via context (120 seconds, generous for a 20-file merge). Stderr captured so failures surface to the user instead of vanishing. Done.&lt;/p&gt;

&lt;h2&gt;
  
  
  The migration we didn't write
&lt;/h2&gt;

&lt;p&gt;This is the bit we're most pleased with.&lt;/p&gt;

&lt;p&gt;Our conversion_jobs table looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;conversion_jobs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;              &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user_id&lt;/span&gt;         &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;source_format&lt;/span&gt;   &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;target_format&lt;/span&gt;   &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;source_size&lt;/span&gt;     &lt;span class="nb"&gt;BIGINT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;output_size&lt;/span&gt;     &lt;span class="nb"&gt;BIGINT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;duration_ms&lt;/span&gt;     &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;output_path&lt;/span&gt;     &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;page_count&lt;/span&gt;      &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;expires_at&lt;/span&gt;      &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For convert flows, &lt;code&gt;source_format&lt;/code&gt; and &lt;code&gt;target_format&lt;/code&gt; are things like &lt;code&gt;'jpg'&lt;/code&gt; and &lt;code&gt;'webp'&lt;/code&gt;. The first instinct for PDF merge was to add a &lt;code&gt;kind&lt;/code&gt; enum column ('convert' | 'pdf_merge' | ...) and store input file paths in a new JSONB column.&lt;/p&gt;

&lt;p&gt;we almost wrote that migration. Then we noticed: the existing schema already represents everything we need. For PDF merge:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;source_format = 'pdf'&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;target_format = 'pdf-merge'&lt;/code&gt; (synthetic — won't match any AllowedTarget, so it never accidentally hits the convert flow)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;page_count = N&lt;/code&gt; where N is the number of input files (reuses the column meaningfully; "page count" of an N→1 merge = input count)&lt;/li&gt;
&lt;li&gt;The existing 1-hour anon TTL applies&lt;/li&gt;
&lt;li&gt;The existing cleanup goroutine cleans up the output&lt;/li&gt;
&lt;li&gt;The existing per-IP anonymous quota counts merges as conversions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Zero migration. Zero new columns. Zero data model debt. The whole feature ships with a parallel &lt;code&gt;MergePDFs&lt;/code&gt; service method and a new HTTP handler, both reusing the existing repository and storage paths.&lt;/p&gt;

&lt;p&gt;This pattern — synthetic target format as a discriminator — extends cleanly to upcoming features (image → PDF will be &lt;code&gt;source='image'&lt;/code&gt;, &lt;code&gt;target='pdf-create'&lt;/code&gt;; OCR will be &lt;code&gt;target='pdf-ocr'&lt;/code&gt;). we get an enum-like discriminator without paying the migration tax.&lt;/p&gt;

&lt;h2&gt;
  
  
  The day 8 honesty section
&lt;/h2&gt;

&lt;p&gt;Building in public means showing the unflattering numbers, so here are mine after one week:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;15 unique visitors total&lt;/strong&gt; (mostly us testing — self-traffic exclude was set up on day 6)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0 confirmed real conversions&lt;/strong&gt; from external users&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0 email signups&lt;/strong&gt; (the form has been live for a week)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 reactions, &amp;lt;25 views, 0 comments&lt;/strong&gt; on the day-4 AVIF crosspost on DEV.to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Almost every solo-founder Twitter post conveniently leaves these numbers out. They're the reality of week 1. The funnel data on our dashboard says the product converts at 33% (visitor → upload → output), which sounds impressive — and is meaningless when 4 of those 5 visitors are us checking a deploy.&lt;/p&gt;

&lt;p&gt;The bottleneck is distribution, not the product. we built PDF merge partially because we needed it, partially because "pdf merge" is a 600K/month search query and our privacy angle has a real wedge against Smallpdf et al. Whether that wedge is enough to grow past 2 visitors/day is the experiment of the next 4 weeks.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Image → PDF (combine multiple images into one PDF) — same pdfunite-style pipeline, just with ImageMagick on the way in&lt;/li&gt;
&lt;li&gt;OCR via Tesseract — much harder; weeks of work&lt;/li&gt;
&lt;li&gt;Distribution: awesome-list PRs, this DEV.to post, then HackerNews "Show HN" once the feature has 2 weeks of stability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try the merger here: &lt;a href="https://swapfile.io/en/tools/pdf-merge" rel="noopener noreferrer"&gt;swapfile.io/en/tools/pdf-merge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code is closed-source today (might change post-monetization in November). Everything you see in this post is exactly how it runs in production — no oversimplification for the article.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building &lt;a href="https://swapfile.io" rel="noopener noreferrer"&gt;SwapFile.io&lt;/a&gt; in public — privacy-first image and PDF tools. Files auto-delete in 1 hour, no Google Analytics, free for the first 6 months. Feedback welcome via reply or &lt;a href="https://twitter.com/swapfileio" rel="noopener noreferrer"&gt;Twitter @swapfileio&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>go</category>
      <category>sideprojects</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>What Is AVIF? Why It Became the Default Image Format in 2026</title>
      <dc:creator>swapfileio</dc:creator>
      <pubDate>Wed, 13 May 2026 21:22:48 +0000</pubDate>
      <link>https://dev.to/swapfileio/what-is-avif-why-it-became-the-default-image-format-in-2026-4kf9</link>
      <guid>https://dev.to/swapfileio/what-is-avif-why-it-became-the-default-image-format-in-2026-4kf9</guid>
      <description>&lt;p&gt;&lt;strong&gt;In this article:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;What AVIF actually is, who built it, what problem it solves&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Why the same image is ~50% smaller than JPEG and ~20% smaller than WebP at equivalent quality&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When AVIF is the right call — and when it isn't&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;2026 browser support: is it finally safe to use everywhere?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let us start with one number. The same 1920×1080 photo, encoded at the quality where the human eye can't tell them apart:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;JPEG at q75: &lt;strong&gt;263 KB&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;WebP at q75: &lt;strong&gt;168 KB&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AVIF at q50: &lt;strong&gt;102 KB&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Three formats. Same image. Same perceived quality. The AVIF version is &lt;strong&gt;less than 40% the size of JPEG&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That single number is why we're having this conversation in 2026. But "use AVIF" is the easy answer. The harder, more useful one is &lt;em&gt;when&lt;/em&gt; to use it — and when not to. That's what this guide covers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is AVIF, Briefly
&lt;/h2&gt;

&lt;p&gt;AVIF stands for &lt;strong&gt;AV1 Image File Format&lt;/strong&gt;. It was released in 2019 by the &lt;a href="https://aomedia.org/" rel="noopener noreferrer"&gt;Alliance for Open Media&lt;/a&gt;, a consortium of companies that wanted a royalty-free, open-source image compression standard. The roster includes Google, Mozilla, Cisco, Apple, Netflix, Amazon — basically the companies that pay the most in bandwidth costs and care the most about open standards.&lt;/p&gt;

&lt;p&gt;Why a new format at all? The image format landscape in 2019 looked like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;JPEG&lt;/strong&gt; (1992): Still everywhere. Still 34 years old.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;PNG&lt;/strong&gt; (1996): Lossless, but huge for photos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HEIC&lt;/strong&gt; (2015): Apple-developed, used by iPhones. Patent-encumbered, expensive to license.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;WebP&lt;/strong&gt; (2010): Google's attempt to replace JPEG. Got stuck because Safari took a decade to support it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The opening: a modern, royalty-free format that actually used the latest compression research. AVIF is built on top of the &lt;strong&gt;AV1 video codec&lt;/strong&gt; — the same codec YouTube and Netflix use for HD/4K streaming. AVIF is essentially "one frame of AV1 video, saved as an image."&lt;/p&gt;

&lt;p&gt;The result: the full power of modern video compression, applied to a single still image.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Actually Works
&lt;/h2&gt;

&lt;p&gt;You can skip this section if you don't care about the technical details — but understanding the basics helps you make better calls about when AVIF helps and when it doesn't.&lt;/p&gt;

&lt;p&gt;AVIF compresses an image by &lt;strong&gt;breaking it into blocks&lt;/strong&gt; (anywhere from 8×8 to 128×128 pixels). For each block, the encoder &lt;em&gt;predicts&lt;/em&gt; what it should look like based on neighboring blocks, then stores only the difference between the prediction and the actual content.&lt;/p&gt;

&lt;p&gt;Imagine you're encoding a photo of a sky. You've got 10 nearly-identical blocks of blue. AVIF says "look at the first block, the next 9 are basically the same with tiny corrections." That's &lt;strong&gt;intra-frame prediction&lt;/strong&gt;, and JPEG doesn't have it. JPEG compresses every block independently. That's why JPEG creates visible banding in gradients — skies, sunsets, blurry backgrounds.&lt;/p&gt;

&lt;p&gt;Two other technical wins worth mentioning:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wider color depth.&lt;/strong&gt; JPEG is locked to 8-bit per channel (256 shades). AVIF supports 10 and 12-bit (1024 and 4096 shades). This matters for HDR photos — JPEG literally can't store HDR information; AVIF can.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alpha channel.&lt;/strong&gt; Transparency, like PNG. AVIF supports it, JPEG doesn't, and AVIF transparent images are typically 60-80% smaller than equivalent PNGs.&lt;/p&gt;

&lt;h2&gt;
  
  
  AVIF vs WebP vs JPEG — Real Numbers
&lt;/h2&gt;

&lt;p&gt;we tested the same 1920×1080 photo across all three formats, calibrating quality settings so the &lt;em&gt;perceptual&lt;/em&gt; quality (measured with DSSIM) was identical:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;File size&lt;/th&gt;
&lt;th&gt;vs JPEG&lt;/th&gt;
&lt;th&gt;Encode time&lt;/th&gt;
&lt;th&gt;Browser support&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;JPEG (q75)&lt;/td&gt;
&lt;td&gt;263 KB&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;&amp;lt;100ms&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebP (q75)&lt;/td&gt;
&lt;td&gt;168 KB&lt;/td&gt;
&lt;td&gt;64%&lt;/td&gt;
&lt;td&gt;~200ms&lt;/td&gt;
&lt;td&gt;97%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AVIF (q50)&lt;/td&gt;
&lt;td&gt;102 KB&lt;/td&gt;
&lt;td&gt;39%&lt;/td&gt;
&lt;td&gt;~1500ms&lt;/td&gt;
&lt;td&gt;94%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AVIF (q30)&lt;/td&gt;
&lt;td&gt;65 KB&lt;/td&gt;
&lt;td&gt;25%&lt;/td&gt;
&lt;td&gt;~2000ms&lt;/td&gt;
&lt;td&gt;94%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Three takeaways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. AVIF wins on file size by a wide margin.&lt;/strong&gt; Same visible quality, 60-75% less storage. The bandwidth savings are massive, especially for mobile users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Encoding is slow.&lt;/strong&gt; JPEG encodes in 50ms, AVIF can take 1.5 seconds for the same image. This isn't a user-facing problem (you only encode once), but it matters for batch jobs. AVIF uses significantly more server CPU.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Browser support is 94%.&lt;/strong&gt; That means 6% of your visitors can't see AVIF. This is why &lt;strong&gt;fallback strategy still matters&lt;/strong&gt; (more on that below).&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use AVIF (and When Not)
&lt;/h2&gt;

&lt;p&gt;Switching every image to AVIF tomorrow is &lt;em&gt;not&lt;/em&gt; the right move. Some use cases make sense, some don't. Here's how we think about it:&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Use AVIF
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Web hero images&lt;/strong&gt; — Page speed is critical, bandwidth matters, 6% fallback is acceptable&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Photography portfolios&lt;/strong&gt; — High resolution, lots of files, storage costs add up&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;E-commerce product images&lt;/strong&gt; — Page load impacts conversion, milliseconds count&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Blog cover images&lt;/strong&gt; — Core Web Vitals affect SEO rankings&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HDR photos&lt;/strong&gt; — JPEG can't preserve HDR; AVIF can&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Transparent backgrounds&lt;/strong&gt; — Replace PNG, get 80% smaller files&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ❌ Don't Use AVIF (yet)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Email content&lt;/strong&gt; — Many email clients still don't render AVIF (Outlook 2019 doesn't)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Legacy systems&lt;/strong&gt; — Enterprise B2B tools, government portals&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Print pipeline&lt;/strong&gt; — If it's going to PDF/PSD eventually, use JPEG/PNG&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Older Photoshop workflows&lt;/strong&gt; — Pre-2022 versions can't open AVIF directly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Internal admin panels where speed doesn't matter&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🟡 The Hybrid Approach (What we Actually Do)
&lt;/h3&gt;

&lt;p&gt;In practice, we generate &lt;strong&gt;three versions of every image&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;AVIF (modern browsers)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;WebP (older Chrome/Firefox)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JPEG (universal fallback)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then let the browser pick using the &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;`&lt;span class="nt"&gt;&amp;lt;picture&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt; &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"hero.avif"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"image/avif"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt; &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"hero.webp"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"image/webp"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"hero.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/picture&amp;gt;&lt;/span&gt;
`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser checks in order: Does it support AVIF? Yes → load AVIF. No? WebP? Also no? Load the JPEG. Every visitor gets the smallest file their browser can handle.&lt;/p&gt;

&lt;p&gt;This triples your storage cost (three copies of each image), but bandwidth savings usually make up for it. If you're paying for a CDN, the numbers work out fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  Browser Support in 2026
&lt;/h2&gt;

&lt;p&gt;Last time we checked &lt;a href="http://caniuse.com" rel="noopener noreferrer"&gt;caniuse.com&lt;/a&gt; (early 2026), AVIF support looks like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Chrome&lt;/strong&gt; — Since August 2020 (5+ years)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Firefox&lt;/strong&gt; — Since October 2021 (4+ years)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Safari&lt;/strong&gt; — Since March 2023 (Safari 16.4+)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Edge&lt;/strong&gt; — Since January 2024 (version 121+)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;iOS Safari&lt;/strong&gt; — Since March 2023&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total global coverage: &lt;strong&gt;~94%&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What this means: Using AVIF in 2024 was an "early adopter" move. &lt;strong&gt;In 2026, it's a standard choice.&lt;/strong&gt; You still need to think about the 6% fallback — that's what &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; solves.&lt;/p&gt;

&lt;p&gt;If your audience skews corporate (Internet Explorer might still be alive in some IT departments!) or is heavy on older Asian Samsung devices, that 94% might be lower for you. Check your actual analytics before assuming.&lt;/p&gt;

&lt;h2&gt;
  
  
  *&lt;em&gt;Converting to AVIF with *&lt;/em&gt;&lt;a href="http://SwapFile.io" rel="noopener noreferrer"&gt;&lt;strong&gt;SwapFile.io&lt;/strong&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;This is exactly the problem &lt;a href="http://SwapFile.io" rel="noopener noreferrer"&gt;SwapFile.io&lt;/a&gt; was built for. You want to convert old JPEGs to AVIF, but you don't have Photoshop, you don't know ImageMagick from the command line, and you definitely don't want to upload your family photos to some random cloud service.&lt;/p&gt;

&lt;p&gt;Our &lt;a href="https://swapfile.io/en/tools/jpg-to-avif" rel="noopener noreferrer"&gt;JPEG to AVIF converter&lt;/a&gt; handles this directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Drop the file in the browser (under 1 second)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Conversion happens on our server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Files auto-delete after 1 hour&lt;/strong&gt; — we never see them, no third party has access&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No cloud storage. No account required (up to 15MB without signup)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also support PNG, HEIC, WebP, GIF, and a few others — all convertible to AVIF. The full &lt;a href="https://swapfile.io/en/tools/" rel="noopener noreferrer"&gt;tools page&lt;/a&gt; lists every supported conversion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why can't we see AVIF thumbnails in Windows Explorer?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Windows 11 doesn't ship with AVIF support by default. Install the &lt;strong&gt;AV1 Video Extension&lt;/strong&gt; from the Microsoft Store (it's free). Once installed, File Explorer will show thumbnails automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Photoshop won't open our AVIF file.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Photoshop &lt;strong&gt;CC 2022 (version 23.2)&lt;/strong&gt; and later support AVIF natively. If you're on an older version, either upgrade or &lt;a href="https://swapfile.io/en/tools/avif-to-jpg" rel="noopener noreferrer"&gt;convert AVIF back to JPEG&lt;/a&gt; first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is AVIF quality worse than JPEG?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At the same file size, AVIF is &lt;strong&gt;better&lt;/strong&gt;. At the same quality, AVIF is &lt;strong&gt;smaller&lt;/strong&gt;. So: JPEG at quality 80 looks the same as AVIF at quality 50, but the AVIF is half the size. At very low quality settings (q20 or below), both formats produce visible artifacts, but AVIF generally degrades more gracefully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will AVIF preserve HDR from our iPhone photos?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. AVIF supports 10-bit and 12-bit HDR. JPEG can't store HDR information (8-bit limit). If you've shot HDR on an iPhone Pro and want to preserve it when moving to a PC, AVIF is the right format.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Should we convert PNG files with transparency to AVIF?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Usually yes. PNG-to-AVIF conversion typically saves &lt;strong&gt;60-80% on file size&lt;/strong&gt; while preserving the alpha channel. The exception: tiny icons (16×16, 32×32) — at that size PNG is already small, and AVIF's encoding overhead negates the savings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does AVIF hurt mobile performance?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Decoding AVIF is 2-3x slower than JPEG, but on modern mobile devices the difference is measured in milliseconds. The &lt;strong&gt;smaller file size = faster network download&lt;/strong&gt; more than compensates. Net effect: faster page loads on mobile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does using AVIF help SEO?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not directly. But it improves &lt;strong&gt;Core Web Vitals&lt;/strong&gt; (specifically LCP — Largest Contentful Paint), which is a Google ranking factor. Switching to AVIF typically drops LCP by 200-500ms. So: indirectly, yes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;One sentence: &lt;strong&gt;AVIF should be your default web image format in 2026, paired with a fallback strategy.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Exceptions: email, print pipelines, legacy systems. In those, stick with JPEG/PNG.&lt;/p&gt;

&lt;p&gt;If you're currently serving JPEG and care about page speed (e-commerce, blog, portfolio), switching to AVIF typically pays back in bandwidth savings within &lt;strong&gt;1-3 months&lt;/strong&gt;. Encoding time is a one-time cost. Storage costs increase slightly. Bandwidth savings are continuous.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your next step:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Convert 5 different photo types using &lt;a href="https://swapfile.io/en/tools/jpg-to-avif" rel="noopener noreferrer"&gt;our AVIF converter&lt;/a&gt; (portrait, landscape, product shot, screenshot, HDR)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compare side by side — same quality? Yes → look at the file size difference&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Convert the 10 most-used images on your site/blog to AVIF&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; tag fallback to your HTML&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Re-run PageSpeed Insights — watch LCP drop&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Related Reading:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://swapfile.io/en/blog/webp-vs-jpeg-2026" rel="noopener noreferrer"&gt;WebP vs JPEG: A 2026 Comparison&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://swapfile.io/en/blog/what-is-heic" rel="noopener noreferrer"&gt;What Is HEIC? Why Windows Can't Open iPhone Photos&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://swapfile.io/en/blog/lossy-vs-lossless" rel="noopener noreferrer"&gt;Lossy vs Lossless: Which Image Compression Should You Use?&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://swapfile.io/en/blog/what-is-avif" rel="noopener noreferrer"&gt;SwapFile.io&lt;/a&gt;. we're building SwapFile.io in public — a privacy-first image converter (HEIC, AVIF, WebP, JPG, PNG, BMP, TIFF, PDF). Files auto-delete in 1 hour, no Google Analytics, free for the first 6 months. Try it: &lt;a href="https://swapfile.io" rel="noopener noreferrer"&gt;swapfile.io&lt;/a&gt;. Feedback welcome.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>performance</category>
      <category>images</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
