{"id":11040,"library":"hls.js","title":"HLS.js - JavaScript HLS Client","description":"HLS.js is a robust, open-source JavaScript library that implements an HLS (HTTP Live Streaming) client. It enables the playback of HLS streams directly in modern web browsers by leveraging the Media Source Extensions (MSE) API, eliminating the need for native browser HLS support. The current stable version is 1.6.16, with frequent patch releases addressing bug fixes and performance improvements. An active pre-release series, such as 1.7.0-alpha.1, indicates continuous development and upcoming significant changes. HLS.js differentiates itself through its extensive feature set, including adaptive bitrate streaming, DVR support, low-latency HLS (LL-HLS), DRM (via EME), CEA-608/708 captions, WebVTT subtitles, and advertising insertion, making it a comprehensive solution for HLS playback in web applications.","status":"active","version":"1.6.16","language":"javascript","source_language":"en","source_url":"https://github.com/video-dev/hls.js","tags":["javascript","typescript"],"install":[{"cmd":"npm install hls.js","lang":"bash","label":"npm"},{"cmd":"yarn add hls.js","lang":"bash","label":"yarn"},{"cmd":"pnpm add hls.js","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Hls.js is primarily an ESM module since v1.0.0, especially when bundled. Using `require` will result in a dummy object in Node.js or import errors in browser environments.","wrong":"const Hls = require('hls.js');","symbol":"Hls","correct":"import Hls from 'hls.js';"},{"note":"Event constants are exposed as static properties of the default `Hls` export. Direct named import of `Events` is incorrect.","wrong":"import { Events } from 'hls.js';","symbol":"Hls.Events","correct":"import Hls from 'hls.js';\nhls.on(Hls.Events.MANIFEST_PARSED, handler);"},{"note":"When using TypeScript, configuration types like `HlsConfig` should be imported using `import type` to prevent bundling issues and clarify intent.","wrong":"import { HlsConfig } from 'hls.js';","symbol":"HlsConfig","correct":"import type { HlsConfig } from 'hls.js';"}],"quickstart":{"code":"import Hls from 'hls.js';\n\nconst video = document.getElementById('video') as HTMLVideoElement;\nconst manifestUrl = 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8';\n\nif (Hls.isSupported()) {\n  const hls = new Hls({\n    // Example configuration for a live stream with limited back buffer\n    liveSyncDurationCount: 3,\n    liveMaxLatencyDuration: 10,\n    // workerPath: '/path/to/hls.worker.js' // Required if using ESM build with workers\n  });\n\n  hls.on(Hls.Events.MEDIA_ATTACHED, () => {\n    console.log('Media attached to video element.');\n    hls.loadSource(manifestUrl);\n  });\n\n  hls.on(Hls.Events.MANIFEST_PARSED, (event, data) => {\n    console.log(`Manifest loaded, found ${data.levels.length} quality level(s).`);\n    // Optionally set quality level, e.g., to the highest available\n    // hls.currentLevel = data.levels.length - 1;\n    video.play();\n  });\n\n  hls.on(Hls.Events.ERROR, (event, data) => {\n    if (data.fatal) {\n      console.error(`Hls.js fatal error: ${data.type} - ${data.details}`, data);\n      switch (data.type) {\n        case Hls.ErrorTypes.NETWORK_ERROR:\n          console.error('Network error detected, trying to recover...');\n          hls.startLoad();\n          break;\n        case Hls.ErrorTypes.MEDIA_ERROR:\n          console.error('Media error detected, trying to recover...');\n          hls.recoverMediaError();\n          break;\n        default:\n          // Cannot recover\n          hls.destroy();\n          break;\n      }\n    }\n  });\n\n  hls.attachMedia(video);\n} else if (video.canPlayType('application/vnd.apple.mpegurl')) {\n  // Native HLS support for Safari, etc.\n  video.src = manifestUrl;\n  video.addEventListener('loadedmetadata', () => {\n    video.play();\n  });\n} else {\n  console.error('This browser does not support HLS playback.');\n}\n","lang":"typescript","description":"This quickstart demonstrates how to initialize HLS.js, attach it to an HTML5 video element, load an HLS manifest, and handle common fatal errors for recovery. It includes a check for browser compatibility and a fallback for native HLS playback."},"warnings":[{"fix":"Migrate your project to use ES module `import` syntax. If using bundlers like Webpack with ESM, ensure the `workerPath` configuration option is set to point to `dist/hls.worker.js` if web workers are enabled. For older browser support, consider using the UMD/ES5 build or specific polyfills.","message":"HLS.js v1.0.0 and above transitioned to an ESM-first architecture. Projects relying on CommonJS `require()` or older browser compatibility (e.g., Internet Explorer) will encounter breaking changes. This also affects how web workers are configured when using bundlers with ESM.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Refer to the HLS.js documentation on DRM and Encrypted Media Extensions (EME). Ensure correct manifest generation, key server responses, and `EXT-X-KEY` tag attributes. Updates in HLS.js v1.6.15 and v1.6.12 specifically address PlayReady and FairPlay parsing issues.","message":"Content Protection (DRM) setups, particularly for PlayReady and FairPlay Streaming, are complex and frequently involve specific platform requirements and manifest parsing nuances. Common issues include incorrect key ID handling or endianness problems, leading to 'keyId is null' errors or failed decryption.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Applications implementing manual quality switching should explicitly pause the video (`video.pause()`) or set `video.playbackRate = 0` before changing `hls.currentLevel` and resume playback (`video.play()`) once the level switch is complete to prevent stalls.","message":"The `hls.currentLevel` property no longer pauses the media element by default when switching quality levels. This change can lead to stall errors if playback doesn't resume quickly enough after a level change, particularly in manual quality switching implementations.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"HLS.js is a browser-specific library relying on Media Source Extensions. It is not designed for server-side processing or Node.js environments. Implement browser-side logic for HLS playback.","message":"HLS.js cannot be instantiated or used in Node.js environments. Attempting to `require()` or `import` the library in Node.js will result in a dummy object being exported, and no HLS playback functionality will be available.","severity":"gotcha","affected_versions":"*"},{"fix":"Avoid using alpha releases in production environments unless specifically testing new features. Consult the v1.7.0 milestone page and planning board on GitHub for detailed changes and migration guidance when a stable v1.7.0 is released.","message":"The `v1.7.0-alpha.x` releases introduce a number of significant changes that are likely to be breaking. These are not feature-complete and are intended for early testing and feedback.","severity":"breaking","affected_versions":">=1.7.0-alpha.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure HLS.js is imported using `import Hls from 'hls.js';` in modern module environments, or that the library's UMD build is loaded via a `<script>` tag before it's referenced, making `Hls` available globally.","cause":"HLS.js was not properly imported or made globally available (e.g., when using a CDN script without a global `Hls` object, or incorrect module import).","error":"Uncaught ReferenceError: Hls is not defined"},{"fix":"Verify the manifest URL is correct and accessible. Check browser developer tools for network errors (404, 403, CORS issues) and server logs. Ensure the server is correctly configured to serve `.m3u8` files with appropriate MIME types and CORS headers. Load the manifest URL directly in a browser to confirm accessibility.","cause":"The HLS manifest (.m3u8 file) could not be retrieved or parsed due to an incorrect URL, network issues, CORS restrictions, or server configuration problems.","error":"HLS.js error: networkError - fatal: true - manifestLoadError"},{"fix":"Review your DRM configuration, license server URL, and key acquisition process. Ensure `keyDrmSystem` is correctly specified and that the license server is responding with valid decryption keys for the content. Check browser console for EME-specific errors.","cause":"This error indicates a problem with the Encrypted Media Extensions (EME) setup for DRM, specifically that no valid decryption keys were provided or could be obtained from the license server. This often occurs with FairPlay Streaming, PlayReady, or Widevine.","error":"Hls.js fatal error: keySystemError - keySystemNoKeys"},{"fix":"Implement a fallback for browsers without MSE support. For iOS Safari, this typically means directly assigning the HLS manifest URL to the `<video src>` attribute, as Safari has native HLS support. For other unsupported browsers, display an error message or provide an alternative player.","cause":"The browser or device does not support the Media Source Extensions (MSE) API, which HLS.js relies upon for playback. This is common on older browsers or some mobile Safari versions (which have native HLS support).","error":"MediaSource is not supported"},{"fix":"Implement error recovery mechanisms using `hls.recoverMediaError()` for `MEDIA_ERROR`. Check network conditions, server performance, and stream health. Adjust HLS.js configuration parameters related to buffering, such as `maxBufferLength` or `maxMaxBufferLength`, or `liveMaxLatencyDuration` for live streams.","cause":"The video buffer has stalled, meaning HLS.js could not append new media segments fast enough, leading to playback interruption. This can be caused by network issues, slow servers, incorrect segment parsing, or excessive buffering limits.","error":"HLS.js error: mediaError - fatal: true - bufferStalledError"}],"ecosystem":"npm"}