HLS vs DASH in 2026: A Plain-English Comparison for Creators and Devs
If you’ve spent more than ten minutes reading about HTTP video streaming, you’ve hit the same wall everyone hits: every comparison of HLS and DASH is written by a company that sells you both. Mux ships them. Cloudflare ships them. Dacast, Bitmovin, AWS — same story. Their honest answer is “use whichever, we’ll handle it,” which is correct but useless if you’re an indie dev wiring up a player, a creator trying to figure out why your stream doesn’t work on iPhone, or a student writing a thesis on adaptive streaming.
This post is the comparison without the upsell. We’ll cover what actually differs, what’s converged, and when the choice matters in 2026.
The 30-second answer
HLS is HTTP Live Streaming, originally shipped by Apple in 2009 as the way to stream video on the iPhone without Flash. It’s now an IETF standard (RFC 8216) and the default streaming protocol for almost every Apple device, most CDNs, and a huge swath of the open web. If you’ve watched anything on an iPhone, an Apple TV, or in Safari, you’ve watched HLS.
DASH is MPEG-DASH, the international standard ratified in 2012 as ISO/IEC 23009. It’s protocol-agnostic about codecs, was designed without any single vendor’s ecosystem in mind, and is the format YouTube uses to deliver most of its video, plus Netflix, plus a chunk of European and Asian streamers. If you’ve watched anything on a Smart TV, an Android device through YouTube, or on most non-Apple platforms, you’ve watched DASH at some point.
CMAF (Common Media Application Format, MPEG-A Part 19) is the third name you need to know. It’s the segment format that both HLS and DASH can use, which means in 2026 you can encode your video once and ship the same segments under both manifests. This is why most of the “HLS vs DASH” wars from 2017 are over — at the byte level, modern HLS and modern DASH often look identical.
So why does the comparison still matter? Because the manifests are different, the DRM stacks are different, the player libraries are different, and the platform support is different. CMAF unified the segments, not the surface area.
Format internals: manifests, containers, encryption
The two protocols solve the same problem — chop video into chunks and describe how to assemble them — but they describe it differently.
HLS manifests are .m3u8 files. They’re a plain-text format derived from the Winamp playlist format from 1999. A master playlist points to one or more media playlists, each of which is a list of segment URLs with durations and metadata. They’re trivial to read, trivial to hand-edit, and trivial to parse. If you’ve never opened one, drop a manifest URL into our m3u8 info inspector — you’ll see something like:
#EXTM3U
#EXT-X-VERSION:7
#EXT-X-TARGETDURATION:6
#EXTINF:6.000,
segment0.ts
#EXTINF:6.000,
segment1.ts
That’s it. No XML, no schema, no namespaces. The simplicity is part of why HLS won the developer-tools battle.
DASH manifests are .mpd files. MPD stands for Media Presentation Description, and it’s an XML document with a formal schema. A typical MPD has a Period (a time range), AdaptationSets (groups of streams of the same media type), Representations (specific bitrate/resolution variants), and SegmentTemplates that describe how to compute segment URLs from a pattern. It’s vastly more flexible than .m3u8 — you can describe ad break boundaries, multiple periods, content protection systems, and trick play tracks declaratively — and it’s also a giant pain to hand-write or hand-debug.
Here’s the same kind of stream in MPD form:
<MPD type="static" minBufferTime="PT6S">
<Period>
<AdaptationSet mimeType="video/mp4">
<Representation bandwidth="1500000" codecs="avc1.4d401f">
<SegmentTemplate timescale="1000" duration="6000"
media="seg-$Number$.m4s" initialization="init.mp4"/>
</Representation>
</AdaptationSet>
</Period>
</MPD>
Same six-second segments, same H.264 video, but the description is structural rather than enumerated.
Segment containers is where CMAF flips the table. Classic HLS used MPEG-2 Transport Stream (.ts) segments, a container designed in the 1990s for satellite broadcast that carried a lot of overhead and quirks into the streaming era. Classic DASH used fragmented MP4 (.m4s or fMP4) segments, much closer to the MP4 you already know. Then CMAF said: let’s all use fMP4. HLS added fMP4 support in 2016, and now most modern HLS encoders ship fMP4 segments, which means HLS and DASH can literally point at the same .m4s files.
The summary table:
| HLS | DASH | CMAF (both) | |
|---|---|---|---|
| Manifest | .m3u8 (text) | .mpd (XML) | n/a — segment-level |
| Standard body | IETF (RFC 8216) | ISO/IEC 23009 | ISO/IEC 23000-19 |
| Original container | MPEG-2 TS | fMP4 | fMP4 |
| Codec scope | H.264, H.265, AV1, AAC, AC-3 | Codec-agnostic | Codec-agnostic |
| DRM | FairPlay (primary), CENC (since 2017) | Widevine, PlayReady, ClearKey via CENC | Common Encryption |
| Native browser | Safari, iOS WebView | Edge (legacy MSE), most non-Safari via dash.js | n/a |
| Hand-readable | Yes | Not really | n/a |
Encryption is where the politics show up. HLS originally encrypted segments with AES-128 at the segment level — simple, effective, but not interoperable with the broader DRM world. In 2017 Apple added support for fMP4 + Common Encryption (CENC, ISO/IEC 23001-7), which is what DASH had used from day one. CENC means the segments are encrypted with AES-CTR or AES-CBC at the sample level, and the actual content key is delivered through a DRM system: FairPlay on Apple, Widevine on Chrome/Android, PlayReady on Edge/Xbox/Smart TVs.
In practice: if you want one stream that works everywhere with DRM, you encrypt CMAF segments with CENC, deliver an HLS manifest with FairPlay key info to Apple devices, and a DASH manifest with Widevine + PlayReady ContentProtection elements to everything else. Same bytes, two manifests. This is exactly what the big platforms do.
Where each one actually wins
Once you understand they’re 90% the same under the hood, the question becomes: which manifest do you ship, or do you ship both?
HLS wins on Apple. Hard stop. iOS Safari does not natively play DASH, and it never will. You can play DASH on iOS through MSE in a player library, but only since iOS 17 (2023) and only on iPhone — iPadOS got it slightly earlier, but Apple still treats HLS as the canonical format. If a meaningful fraction of your audience is on iPhone or you’re shipping to Apple TV, HLS is the path of least resistance. If you’re publishing a podcast, Apple Podcasts requires HLS for video podcasts as of late 2023 — DASH is not a substitute.
HLS wins on simplicity. A static HLS stream is a directory of files with a .m3u8 index. You can serve it from S3, from a $5 VPS, from a static CDN, from anywhere that can serve files. No special server, no manifest generator, no XML schema validation. For self-hosters and indie devs, this is enormous. We default to HLS for our HLS converter for exactly this reason — drop the output on any web server and it works.
DASH wins on YouTube and Netflix tier infrastructure. YouTube uses DASH because Google built DASH (sort of — Google was a primary contributor to the spec). Netflix uses DASH because they need PlayReady support for Smart TVs and they have the engineering depth to run their own players. If you’re operating at “we ship our own player to every platform” scale, DASH gives you slightly more control, more declarative manifest features, and historically better support for live-DVR window manipulation.
DASH wins on multi-DRM out of the box. You can declare Widevine, PlayReady, and ClearKey side by side in a single MPD with <ContentProtection> elements. HLS can do this too via SESSION-KEY tags now, but DASH’s model is older and more battle-tested for premium content workflows.
Low-latency is a tie, with caveats. Low-Latency HLS (LL-HLS) shipped in 2020 with partial segments and HTTP/2 push hints. Low-Latency DASH uses CMAF chunks with chunked transfer encoding. Both can hit 2-3 second glass-to-glass latency in production. Both are operationally annoying — partial segments in HLS make manifests update every 200ms, CMAF chunked encoding in DASH requires CDN cooperation that not every CDN has tuned. If sub-second latency is genuinely critical, you’re probably on WebRTC or SRT, not either of these.
Tooling is closer than you’d think. hls.js is the de facto HLS player for browsers that don’t natively support it. dash.js is its DASH counterpart. Shaka Player (Google’s open source player) speaks both. Video.js wraps either. ExoPlayer on Android speaks both. AVPlayer on iOS speaks HLS only. FFmpeg packages both. So at the player layer, the work is mostly the same — pick a library, point it at a manifest.
Where they’re converging
If you started reading streaming docs in 2017 you were told these were two different worlds. In 2026 they’re more like two dialects of the same language.
CMAF is the big convergence point — same segments, two manifests. Common Encryption means the keys can be the same too. Both protocols support all the modern codecs you’d actually use: H.264 for compatibility, H.265 for efficiency on devices that have hardware decode, AV1 where you control the player, AAC and Opus for audio (Opus in DASH is more common; HLS-Opus support landed but isn’t universal yet).
ABR (adaptive bitrate) algorithms are functionally the same across both protocols at the player level — measure throughput, estimate buffer health, pick the next segment’s bitrate. The decisions hls.js makes and the decisions dash.js makes for the same network conditions are within a few percent of each other.
The remaining differences come down to:
- Manifest size and update mechanics for live. HLS manifests are append-only for live; DASH manifests can use $Number$ templates that don’t grow.
- Subtitle and caption handling. HLS uses WebVTT files referenced from the manifest. DASH uses WebVTT or TTML, often inside MP4 sidecar tracks. Subtitle muxing is fiddlier in HLS, which we’ll come back to in the limitations section.
- Trick play and I-frame playlists. HLS has #EXT-X-I-FRAMES-ONLY playlists for fast scrubbing. DASH has trick mode AdaptationSets. Different syntax, similar capability.
- Manifest reusability for ads. SCTE-35 ad markers exist in both, but VAST/VMAP integration and SSAI workflows are slightly more standardized in DASH historically. This is the area where DASH still has a real edge for enterprise.
If you’re not doing server-side ad insertion or premium DRM, the day-to-day difference is roughly: HLS is easier, DASH is more flexible, and CMAF makes the underlying segments interchangeable.
The decision matrix
Here’s the actual flow you should follow as a creator or developer in 2026:
Build for iOS-first or “must work in Safari without a player library” → Ship HLS. iOS will play it natively. You don’t need to bundle a JavaScript player. Done.
Build for “everywhere, but I have one engineer” → Ship HLS. hls.js works on every desktop browser. Apple devices play it natively. Android plays it through ExoPlayer. You’ll lose a sliver of compatibility on a few Smart TVs that prefer DASH, but you’ll save weeks of pipeline complexity.
Build for premium content with multi-DRM (Widevine + PlayReady + FairPlay) → Ship both. Encode CMAF once with CENC, generate HLS for Apple with FairPlay key info, generate DASH for Widevine + PlayReady. This is the Mux/Bitmovin/Cloudflare default for a reason.
Build for YouTube-scale with control over the player → Either works, DASH gives you slightly more declarative power. If you have a player team, you’ve already made this decision based on internal tooling.
Build for hobby projects, self-hosting, podcast distribution, course platforms, indie creator workflows → HLS, every time. Single format, simplest infrastructure, broadest device support, mandated by Apple Podcasts.
Build for ultra-low-latency live (sub-2 second) → Probably neither. Look at WebRTC, SRT, or LL-HLS as a last resort. Both LL-HLS and LL-DASH exist but the operational overhead is significant.
The pattern: unless you have a specific reason to ship DASH, HLS is the default for almost every independent project in 2026. The companies that ship DASH have engineering teams whose full-time job is shipping DASH.
The cutfa.st angle
We’re a browser-only video toolkit. Everything we ship runs in your tab via Mediabunny + WebCodecs — no upload, no server-side processing, your video doesn’t leave your machine. We made an explicit bet on HLS for our streaming features, and we want to be honest about why and what it means.
Why HLS: It’s the format the long tail of the web actually uses. Indie creators on Substack, course platforms on Teachable, podcasts on every Apple-blessed surface, self-hosted streams on someone’s basement Raspberry Pi — these are all HLS. They all need tools to convert into HLS, out of HLS, or to inspect HLS manifests when something breaks at 2am. We built mp4-to-hls to package files for delivery, hls-converter to extract HLS streams into something editable, and m3u8-info to inspect manifests when you’re debugging.
What we don’t do: We do not read DASH. We do not write DASH. We do not transmux from HLS to DASH or back. If you need DASH workflows, your options are FFmpeg locally, Shaka Packager, or a hosted service like Mux. Our manifest inspector handles .m3u8 only — there’s no equivalent for .mpd files in the toolkit, and we don’t currently plan to add one.
Other things we’re honest about: Mediabunny 1.44 (the underlying engine) handles single-rendition HLS output only — you can’t generate a multi-bitrate ABR ladder in the browser yet. We do not mux WebVTT subtitle tracks into HLS output (it’s on the limitation list). We can read DRM-protected HLS for inspection but cannot generate DRM-protected HLS output. We do not support Low-Latency HLS as an output format. If any of these are blockers for your use case, you want a server-side packager, not us.
If you’re working with HLS and want browser-only tools that don’t ship your video to anyone’s cloud, the HLS feature set is built for you. If you’re working with DASH, this is a fair point to bookmark Mux’s documentation and move on.
FAQ
When should I ship both HLS and DASH? When you have premium content that needs multi-DRM (FairPlay for Apple, Widevine for Chrome/Android, PlayReady for Smart TVs and Xbox), or when you have a measurable audience on platforms where DASH is the only option. For everyone else — indie devs, creators, hobby projects — shipping just HLS is fine in 2026.
Can I hand-edit a manifest? HLS, yes — .m3u8 is plain text and you can fix a broken stream by editing it in nano. DASH, technically yes but practically no — .mpd is XML with strict schema requirements, and one missed namespace or attribute will silently break players. If you find yourself hand-editing MPDs regularly, get a tool.
What does Apple Podcasts actually require? For video podcasts, Apple Podcasts requires HLS streams with specific encoding parameters: H.264 video at specific levels, AAC audio, fMP4 segments, and a master playlist plus media playlist structure. The exact spec lives in Apple’s Podcaster Program documentation and updates periodically — check there before publishing. Audio-only podcasts still use plain MP3 or AAC files via RSS, not HLS.
Do I need both hls.js and dash.js? Only if you’re shipping both manifests. If you’re HLS-only, hls.js for non-Safari browsers plus the native HTML5 video element on Safari is enough. If you want one library for both, Shaka Player covers both protocols and is what Google uses internally. The bundle size cost of bundling both is non-trivial — hls.js is around 200KB minified, dash.js is around 400KB.
What are ABR ladder differences between HLS and DASH? At the player level, almost none. Both pick segments based on throughput estimation and buffer health. The differences are in how the manifest expresses the ladder: HLS uses a master playlist with VARIANT entries, DASH uses AdaptationSets with multiple Representations. As long as your ladder rungs are similar (typically 240p/360p/480p/720p/1080p with appropriate bitrates), the playback experience will be functionally identical.
Is CMAF going to make HLS and DASH the same protocol? Not the same protocol — the manifests will always be different. But CMAF has already made the segments the same, and over time both manifests have grown more similar in expressiveness. The realistic future is that you encode CMAF once and serve it under both manifests when you need to, and most projects will only need one.
If I’m using Mux, Cloudflare Stream, or any hosted platform, do I pick? No. They handle this for you, ship both manifests automatically, and route the right one to each player based on user agent. The “HLS vs DASH” question is something you only ask when you’re packaging video yourself. If you’ve outsourced packaging, the answer is “yes, both, please.”
If you’re working with HLS and want fast, browser-only tools — converting to it, extracting from it, inspecting it, trimming it — that’s our toolkit. Drop a manifest into m3u8-info, package an MP4 with mp4-to-hls, or pull an HLS stream into something editable with hls-converter. All client-side, all in your tab, no upload.
More in this series
- The Podcaster's Guide to Audio-Only HLS in 2026 (Apple Podcasts Ready)
- What Is an M3U8 File? Open, Play, Convert to MP4 Free
- Live Stream Replay to Shorts: Turn 4-Hour Streams Into 30 Viral Clips With CutFast (2026 Guide)
- Twitch VOD to Shorts (2026): Download Twitch Clip MP4 or Cut the Full VOD
- M3U8 Downloader Online: Save HLS Streams as MP4 for Free in 2026 (No DevTools, No FFmpeg)
View all 10 articles in HLS, m3u8 & Stream Recording →