Library / SDK
gpac/mp4box.js avatar
gpac/mp4box.js

mp4box.js: MP4 parsing, segmentation and sample extraction in JavaScript

JavaScript version of GPAC's MP4Box tool

2,469 stars390 forksTypeScriptBSD-3-Clause

At a glance

What is it?
mp4box.js is the JavaScript port of GPAC's MP4Box, published to npm as mp4box. It parses MP4 metadata progressively, segments files for MSE and hands you individual samples, but it is a library with a thin README, not a finished player.
Who is it for?
Adopt mp4box.js if you need MP4 box parsing, MSE segmentation or raw sample extraction inside a browser or a Node process, and you are willing to read the demo sources because the README stops well short of a full API reference. Do not adopt it as a playback engine: it hands you metadata and samples, not a rendering pipeline, and the README documents no rollback for an aborted segmentation run.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What mp4box.js does that a video element cannot

The browser gives you playback, not inspection. If you need to know the codec string of each track, the number of samples, the timescale, or the brands declared in the ftyp box, the video element is silent. mp4box.js exists to expose that layer. The package describes itself as the JavaScript version of GPAC's MP4Box tool, and the README frames the API around the same jobs the command line tool performs: reading file information, segmenting, and extracting samples.

The audience is narrow but real. Someone building a Media Source Extensions player needs to turn a progressive MP4 into init and media segments and needs the codec string to construct SourceBuffer objects. Someone building a subtitle or timeline-preview feature needs individual samples, not a decoded frame. Someone building a file inspector needs the moov box parsed and nothing else. The README lists exactly these three cases: inspect metadata, segment for adaptive streaming or MSE playback, extract samples for TextTracks or timeline previews.

It is not a transcoder, not a muxer for arbitrary formats, and not a player. It reads MP4 structure and gives you the pieces.

Progressive parsing and the moov callback chain

The core object is an ISOFile, created with MP4Box.createFile(). You attach callbacks, then feed it ArrayBuffer chunks with appendBuffer, and finish with flush. The README stresses that parsing is progressive: small buffers at a time are fine, and the onReady callback fires once the moov box has been parsed. That is the design decision that matters. Metadata usually sits at the front of a well-formed MP4, so you can learn the track layout before the media data has finished downloading.

Two callbacks bracket that moment. onMoovStart fires when the moov box begins parsing, and the README notes it may take a while to download the whole box depending on download speed. onReady fires when parsing completes and receives an info object. That object carries duration, timescale, the isFragmented and isProgressive booleans, hasIOD, the brands array, created and modified dates, and a tracks array. Each track entry has an id, codec string, bitrate, nb_samples, language, and either a video object with width and height or an audio object with sample_rate, channel_count and sample_size.

The codec field is the practical payoff. The README states it gives the MIME codecs parameter, for example avc1.42c00d or mp4a.40.2, to be used when creating SourceBuffer objects with Media Source Extensions. That single string is the bridge between parsing and playback.

Installing mp4box and reading your first file's metadata

The README gives one installation command and it is the only one you need. The package name on npm is mp4box, not mp4box.js, which trips people up when they search for the repository name.

bash
npm install mp4box@latest

The package requires Node.js 20.8.1 or newer according to the engines field in package.json, so check that before installing. Once installed, the README's example creates a file object, wires up onError and onReady, appends buffers and flushes.

javascript
var MP4Box = require('mp4box'); // Or whatever import method you prefer.
var mp4boxfile = MP4Box.createFile();
mp4boxfile.onError = function(e) {};
mp4boxfile.onReady = function(info) {};
mp4boxfile.appendBuffer(data);
mp4boxfile.appendBuffer(data);
mp4boxfile.appendBuffer(data);
mp4boxfile.flush();

The data variable is an ArrayBuffer you supply, from a fetch response, a file input, or a Node buffer. What you should see is onReady firing once with the info object described above. Log info.tracks and you get one entry per track with its codec string and dimensions. The README does not walk through obtaining the ArrayBuffer; the demo directory is where that plumbing lives, with demo/filereader.html and demo/filereader.js being the inspection example the homepage points at.

For the browser, the package also exports a ./simple entry point alongside the default one, and the build outputs both ESM (.mjs) and CommonJS (.cjs) variants, so the import style depends on your bundler.

Where mp4box.js stops being the right tool

The README is a feature list with an API sketch, not a reference. Large parts of the surface are simply not described there: the segmentation and extraction sections that the use-case list points to are not present in the text available, and the full track information object is truncated mid-field. If your work depends on the exact shape of a callback payload or on a method the README never names, you will be reading the TypeScript sources under src/ or the demo files, not the documentation.

There is a second boundary. mp4box.js parses and splits; it does not decode, render or remux into other containers. If your goal is to convert an MP4 to another format, or to play a file with subtitles burned in, this library is one component of that pipeline at most. It gives you boxes, segments and samples, and expects you to know what to do with them.

Progressive parsing also has a cost the README is honest about: onMoovStart can fire long before onReady, because the moov box may be large and slow to arrive. Code that assumes metadata is available immediately after the first appendBuffer will be wrong. The README documents no rollback or reset path for a parse you want to abandon, so plan for a fresh ISOFile rather than reusing one mid-stream.

mp4box.js against ffmpeg.wasm and the native MP4Box

The obvious alternative on the command line is MP4Box itself, from the GPAC project, which the README names as the inspiration. The difference is deployment, not capability. Native MP4Box is a compiled binary you install on a machine or a server; mp4box.js is a library you ship to the browser, which is the entire reason it exists. If your processing happens server-side and you already have GPAC installed, the JavaScript port adds a runtime dependency without adding reach.

Against ffmpeg.wasm the split is different. ffmpeg.wasm brings a full transcoding toolchain into the browser, which means a much larger download and a WebAssembly boundary between your code and the media. mp4box.js is plain JavaScript and TypeScript, and it does structure work rather than codec work. If you need to re-encode, mp4box.js is not the tool. If you need to know what is inside the file and slice it into MSE-compatible pieces, pulling in an encoder is overkill.

The repository layout reflects that scope. There is a src/ directory, a tests/ directory, and a demo/ directory with separate pages for inspection, segmentation, diffing and an MSE-based AVIF viewer. That demo set is the closest thing to a feature matrix the project publishes.

Release cadence, licence and what upgrades cost you

The last push to the repository was on 2026-09-23, and the most recent release, v2.4.1, was published on 2026-06-19, preceded by v2.4.0 on 2026-06-18 and v2.3.0 on 2025-11-22. The gap between v2.3.0 and v2.4.0 is roughly seven months, and v2.4.1 followed v2.4.0 within a day, which reads as a patch release on top of a larger change. The project is not archived.

Upgrade cost is shaped by the packaging rather than by a migration guide. The package ships dual ESM and CommonJS builds plus TypeScript declarations for both, and exposes a default entry and a ./simple entry. A major-version bump can therefore change both the import path and the type surface at once. The repository uses changesets for release management, so per-release notes live in the .changeset directory and the CHANGELOG rather than in the README, and that is where you should look before bumping.

The licence is BSD-3-Clause, declared in both the LICENSE file and the package.json license field. That is a permissive licence, but it still carries the standard condition about retaining the copyright notice and disclaimer in redistributed source or binary form. If you bundle the library into a shipped product, keep the notice. This is a description of the licence text, not legal advice; read the LICENSE file and talk to your own counsel about your distribution.

Editorial conclusion

Adopt mp4box.js if you need MP4 box parsing, MSE segmentation or raw sample extraction inside a browser or a Node process, and you are willing to read the demo sources because the README stops well short of a full API reference. Do not adopt it as a playback engine: it hands you metadata and samples, not a rendering pipeline, and the README documents no rollback for an aborted segmentation run. Before committing, verify the two things the material leaves open: which entry point you need (the package exports both the default and ./simple), and whether the demo you intend to imitate (filereader, file-segmenter, mse-avif-viewer) is still the one you want, since the demo directory is where most usage patterns actually live.

Frequently asked questions

What is the MP4 container format used for?

The README does not explain the container format itself. It describes mp4box.js as a library for parsing, segmenting and extracting samples from MP4 files, and lists the file brands, tracks, codecs and durations it can read from the moov box.

How do I install mp4box.js?

The README gives a single command, npm install mp4box@latest. The package name on npm is mp4box, and package.json requires Node.js 20.8.1 or newer.

Does mp4box.js work in the browser and in Node.js?

Yes. The README lists cross-platform support as a feature and states the library works in both browser and Node.js environments. The package publishes separate ESM and CommonJS builds for each consumption style.

Can mp4box.js segment an MP4 for MSE playback?

The README lists segmentation as a key feature, describing it as splitting MP4 files for use with the Media Source Extensions API. The codec field in the track info is meant to be passed when creating SourceBuffer objects.

What licence does mp4box.js use?

BSD-3-Clause, as declared in the LICENSE file and the license field of package.json.

Official sources

  1. gpac/mp4box.js on GitHub
  2. License: BSD-3-Clause
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/gpac-mp4box-js.svg)](https://hysenlabs.com/projects/gpac-mp4box-js)