Mediabunny: a TypeScript media toolkit that runs in the browser
Pure TypeScript media toolkit for reading, writing, and converting video and audio files, directly in the browser.
At a glance
- What is it?
- Mediabunny reads, writes and converts MP4, WebM, MP3 and HLS files in JavaScript, with hardware-accelerated codecs through WebCodecs. It is not a browser port of FFmpeg, and that distinction decides whether it fits your project.
- Who is it for?
- Adopt Mediabunny if you are shipping a browser app that needs to read, write or convert media client-side and you can live with WebCodecs as the codec layer; the package is small, tree-shakable and installs with npm install mediabunny. Do not adopt it if your pipeline must run the same codec stack everywhere, or if you need FFmpeg's filter graph.
- Can I use it commercially?
- Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- 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 29, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What Mediabunny is for, and where the server stops being the answer
Uploading a 400 MB video so a server can read its duration is a waste of bandwidth. Mediabunny exists for the cases where the file is already on the user's machine and the operation is cheap enough to do there: pulling metadata, generating a thumbnail, trimming a clip, transcoding to a smaller container before upload. The README frames it as "a bit like FFmpeg, but built from the ground up for the web", which is the right framing because the target is the browser runtime rather than a shell pipeline.
The audience is web engineers who would otherwise reach for a server-side ffmpeg process or a WebAssembly build of it. Mediabunny is written from scratch in pure TypeScript, has zero dependencies, and the repository describes it as extremely tree-shakable, with a bundle as small as 5 kB gzipped when you only pull in what you use. That last property matters more than it sounds: a media library that drags in every container parser is a poor fit for a page that only needs to read an MP4 duration.
The same package also runs outside browsers. The README points to @mediabunny/server for Node, Bun and Deno, so the same API surface can cover a build step and a client-side path. That is a real convenience, but it does not change the codec story, which is the subject of the next section.
How the pieces fit: Input, Output, Conversion and WebCodecs
The architecture splits into three object families. An Input wraps a source and a set of formats, and answers questions about the file: duration, primary video and audio tracks, display dimensions, rotation, sample rate, channel count, metadata tags. An Output wraps a format and a target, and accepts tracks fed by sources such as CanvasSource. Conversion sits between the two and does the work of moving samples from one to the other.
Decoding and encoding are delegated to the WebCodecs API, which the README credits for hardware acceleration across 25+ video, audio and subtitle codecs. Mediabunny's own code handles the container layer: demuxing and muxing MP4, MOV, WebM, MKV, HLS, WAVE, MP3, Ogg, ADTS, FLAC and MPEG-TS, plus the streaming I/O that keeps memory flat on large files. Reading and writing are described as microsecond-accurate.
That division is the whole design. Mediabunny does not ship a codec; it ships the plumbing that turns a file into codec chunks and back. Which means the format list in the README describes what the library can parse and construct, not what your target browser can actually decode. Those are two different lists, and the gap between them is where projects get surprised.
Installing Mediabunny and reading metadata from a file input
Install from npm. The package ships ESM modules, a browser bundle and a Node bundle, resolved through the exports map in package.json.
npm install mediabunnyThe README states the runtime requirement as any JavaScript environment that can run ECMAScript 2021 or later, with TypeScript 5.7 or later for types. There is also a script tag path: the release builds expose a global Mediabunny object, so a plain HTML page can load mediabunny.cjs without a bundler.
The first real use is reading metadata. Import Input, ALL_FORMATS and BlobSource, wrap the file, and query it.
import { Input, ALL_FORMATS, BlobSource } from 'mediabunny';
const input = new Input({
source: new BlobSource(file),
formats: ALL_FORMATS,
});
const duration = await input.computeDuration(); // in seconds
const videoTrack = await input.getPrimaryVideoTrack();
const displayWidth = await videoTrack.getDisplayWidth();Every one of those calls is asynchronous, and the track getters can return nothing when the file has no track of that kind, so the code needs a guard before it touches displayWidth. The README example shows the unguarded version for brevity.
Converting is the same shape with a different middle object. Build an Input, build an Output with the format you want, hand both to Conversion.init, then call execute.
import { Input, Output, Conversion, ALL_FORMATS, BlobSource, WebMOutputFormat } from 'mediabunny';
const input = new Input({ source: new BlobSource(file), formats: ALL_FORMATS });
const output = new Output({ format: new WebMOutputFormat(), target: new BufferTarget() });
const conversion = await Conversion.init({ input, output });
await conversion.execute();After execute resolves, the bytes live in output.target.buffer. The README notes BufferTarget writes to memory, so a long conversion holds the whole result in RAM; the streaming I/O path is the alternative when that is not acceptable.
The WebCodecs dependency is the real constraint
Mediabunny's format support and its codec support are not the same thing, and the README does not blur them, but it is easy to read the feature list and assume the library decodes everything it can parse. It does not. Codec work goes through WebCodecs, which is a browser API with its own availability story. A container Mediabunny can mux perfectly well may contain a codec the current browser refuses to decode, and the failure surfaces at decode time rather than at import time.
This is the case where Mediabunny is the wrong tool. If your product promise is "this file converts, on any device, with identical output", a client-side codec stack tied to browser implementations is a liability you cannot engineer away from inside the library. The same applies to anything needing a filter graph: the Conversion API covers transmuxing, transcoding, resizing, rotation, cropping, resampling and trimming, which is a generous list, but it is a fixed set of operations rather than a composable pipeline.
The README does not document rollback or error-recovery behaviour for a failed conversion, and it does not describe what happens when a track's codec is unsupported mid-stream. Treat those as things to establish by reading the API documentation at mediabunny.dev rather than assuming.
Mediabunny vs FFmpeg: same problem, opposite deployment
The comparison people search for is the right one, because both tools read, write and convert media. The difference is where the code runs and what guarantees it carries.
FFmpeg is a native binary with its own codec implementations. It runs on a server or in a WebAssembly sandbox, and it behaves the same on every machine that runs the same build. Mediabunny is a TypeScript library that runs in the page and delegates codec work to the host browser through WebCodecs. You trade determinism for locality: no upload, no server round trip, no per-minute compute bill, but output depends on the browser and the hardware underneath it.
That trade has a second edge. FFmpeg's filter graph lets you chain arbitrary operations; Mediabunny's Conversion API exposes named operations. If your pipeline is "trim, then apply an audio filter, then overlay", the second and third steps are outside what the README describes. If your pipeline is "read the duration and make a thumbnail", Mediabunny does it without a server and without shipping a multi-megabyte WASM payload.
Licence, release cadence and what upgrading costs
Mediabunny is MPL-2.0. That is a file-level copyleft licence: modifications to Mediabunny's own source files must be made available under the same terms, while your application code that merely imports the library is not pulled into that obligation. This is a description of the licence text, not legal advice; if you intend to fork and redistribute the library itself, have counsel read MPL-2.0 rather than this paragraph.
The release history shows a fast cadence: v1.58.0 on 2026-09-17, v1.58.1 on 2026-09-19, and v1.59.0 on 2026-09-21, with the last push to the default branch on 2026-09-21. Three releases in five days is normal for a project at this stage and it cuts both ways. You get fixes quickly. You also get a moving target, and the version is pinned in your lockfile for a reason.
The upgrade cost is mostly surface area. The package is side-effect free, so bundlers can drop unused parts, but a minor bump can still change the API you call. The repository carries api-extractor.json and a check-docblocks script, which suggests the public type surface is tracked deliberately; still, the practical check before upgrading is running your own conversion path against real files rather than reading the changelog alone.
Editorial conclusion
Adopt Mediabunny if you are shipping a browser app that needs to read, write or convert media client-side and you can live with WebCodecs as the codec layer; the package is small, tree-shakable and installs with npm install mediabunny. Do not adopt it if your pipeline must run the same codec stack everywhere, or if you need FFmpeg's filter graph. Before committing, verify which codecs your target browsers expose through WebCodecs and whether your container and codec combination is listed in the supported format set.
Frequently asked questions
What are the key differences between Mediabunny and FFmpeg?
Mediabunny is a pure TypeScript library that runs in the browser and delegates codec work to WebCodecs, while FFmpeg is a native tool with its own codec implementations that typically runs on a server or as WebAssembly. Mediabunny's Conversion API exposes named operations such as transmuxing, transcoding, resizing, rotation, cropping, resampling and trimming rather than FFmpeg's composable filter graph.
What is Mediabunny?
It is a JavaScript library for reading, writing and converting media such as MP4, WebM, MP3 and HLS directly in the browser. The README describes it as written from scratch in pure TypeScript with zero dependencies, and notes it also runs in Node, Bun and Deno through @mediabunny/server.
What is a Mediabunny alternative if I need deterministic output?
FFmpeg is the natural alternative when you need the same codec output on every machine, since it carries its own codec implementations instead of relying on the browser. The cost is that it runs on a server or as a WebAssembly payload rather than in the page.
Official sources
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.
[](https://hysenlabs.com/projects/vanilagy-mediabunny)
Community notes