dash.js

Reference JavaScript client for playing MPEG-DASH adaptive video streams directly in the browser.

Library
npm
v5.2.1
5,545stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
93/100Excellent
Development Activity96
Maintenance84
Community92
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
88/100Excellent
Architecture88
Code Quality85
Innovation78
Learning Curve100

dash.js is the reference JavaScript implementation for playing MPEG-DASH content in browsers that support the Media Source Extensions (MSE) and Encrypted Media Extensions (EME) APIs. Maintained by the DASH Industry Forum, it wraps manifest parsing, adaptive bitrate switching, buffering, and DRM negotiation behind a single MediaPlayer object that applications instantiate and attach to a video element.

Beyond core DASH playback it also implements Microsoft Smooth Streaming (MSS) compatibility, CMAF and low-latency delivery, offline download/storage, and CMCD reporting, making it the de facto reference client vendors and broadcasters use to validate packagers and test conformance against the DASH-IF spec.

What You Get

  • A MediaPlayer factory API that wraps MSE/EME playback behind a few method calls
  • Pluggable adaptive bitrate (ABR) rules for bandwidth- and buffer-based quality switching
  • Built-in DRM support via the Encrypted Media Extensions (EME) protection module
  • Microsoft Smooth Streaming (MSS) compatibility alongside native DASH
  • CMAF and low-latency streaming support for near-real-time delivery
  • Offline download and storage APIs for saving DASH content for later playback

Common Use Cases

  • Building a custom video player for an OTT or streaming platform
  • Delivering DRM-protected VOD or live content in the browser
  • Powering low-latency live streams (sports, events, auctions)
  • Acting as a reference/conformance target when validating DASH packagers and encoders

Under The Hood

Architecture dash.js is organized around a custom dependency-injection system, FactoryMaker, which every module (controllers, models, parsers) registers with and resolves singleton or context-scoped instances through rather than importing concrete classes directly. Playback flows from MediaPlayerFactory/MediaPlayer down into a Stream/StreamProcessor pipeline that a StreamController coordinates alongside dedicated controllers for buffering, scheduling, ABR, gap handling, and media source management, with the codebase split into clearly bounded top-level modules (dash, mss, streaming, offline, core) so protocol-specific parsing (DASH vs. Smooth Streaming) stays isolated from the shared playback engine. Replacing a core abstraction such as the ABR controller or the FactoryMaker container itself would ripple through nearly every other module, since almost all of them are instantiated and wired together through it.

Tech Stack The library is plain ES modules with no runtime framework dependency, published as both modern (ESM/UMD) and legacy transpiled bundles built via Webpack and Babel, with TypeScript used only for authoring and shipping ambient type declarations (index.d.ts) rather than as the implementation language. Documentation is built with VitePress and JSDoc, and the project ships CMCD, protection (EME/DRM), and offline (IndexedDB-backed) modules as first-class parts of the same package rather than separate add-ons.

Code Quality The project has an extensive unit test suite (over a hundred spec files) run through Karma across multiple browser launchers, using Mocha, Chai, and Sinon for assertions and mocking, backed by a dedicated ESLint configuration and CI workflows that gate pull requests on build, lint, and test passing. Error handling is centralized through an ErrorsBase/Errors class hierarchy per module (core, dash, mss, offline) that assigns structured numeric codes and messages rather than throwing bare exceptions, and naming conventions are consistent across the controller/model/vo layering.

API Design The public surface is intentionally small at the entry point: dashjs.MediaPlayer(context).create() followed by initialize() gets a working player attached to a video element, while deeper configuration is exposed through a comprehensive Settings object and a large, well-documented event bus (MediaPlayerEvents) rather than dozens of constructor parameters. The extensive TypeScript ambient definitions and generated API docs make the surface discoverable, though the sheer breadth of configuration options and controllers means real customization still requires reading past the quickstart.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search