# @wordpress/video-conversion

> Client-side video conversion for WordPress. Currently converts animated GIFs to MP4/WebM via WebCodecs.

Latest version **0.6.0** (published 2026-09-10) · GPL-2.0-or-later license · 0 weekly downloads

## Install

```sh
npm install @wordpress/video-conversion
pnpm add @wordpress/video-conversion
yarn add @wordpress/video-conversion
bun add @wordpress/video-conversion
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; popular repo.

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.6.0 |
| Published | 2026-09-10 |
| First published | 2026-07-07 |
| Weekly downloads | 0 |
| License | GPL-2.0-or-later |
| TypeScript types | bundled |
| Module format | ESM |
| Node | >=18.12.0 |
| Dependencies | 2 |
| Unpacked size | 2.7 MB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 11753 |
| Author | The WordPress Contributors |
| Maintainers | garypendergast, adamsilverstein, gziolo, ntwb, riad, noisysocks, kadamwhite, gutenbergplugin, jorgefilipecosta, ellatrix, iandunn206, whyisjake, ockham, sirreal, nosolosw, wpisabel, ntsekouras, nerrad, desrosj, talldanwp, peterwilsoncc, ryanwelcher, mamaduka, aduth, johnbillion |
| Keywords | wordpress, media, video, webcodecs, gif |

## Links

- npm: https://www.npmjs.com/package/@wordpress/video-conversion
- Repository: https://github.com/WordPress/gutenberg
- Homepage: https://github.com/WordPress/gutenberg/tree/HEAD/packages/video-conversion/README.md
- Issues: https://github.com/WordPress/gutenberg/issues
- npm.io page: https://npm.io/package/@wordpress/video-conversion

## Dependencies (2)

- [mediabunny](https://npm.io/package/mediabunny.md) ^1.45.2
- [@wordpress/worker-threads](https://npm.io/package/@wordpress/worker-threads.md) ^1.15.0

## Alternatives

- [@sindresorhus/slugify](https://npm.io/package/@sindresorhus/slugify.md) — 3.7M weekly downloads
- [solid-js](https://npm.io/package/solid-js.md) — 2.7M weekly downloads
- [expo-glass-effect](https://npm.io/package/expo-glass-effect.md) — 2.5M weekly downloads
- [nanoassert](https://npm.io/package/nanoassert.md) — 780.8K weekly downloads
- [@ffmpeg/ffmpeg](https://npm.io/package/@ffmpeg/ffmpeg.md) — 529.5K weekly downloads

## Recent versions

- 0.6.0 (latest) — 2026-09-10
- 0.5.2-next.v.202609031004.0 (next) — 2026-09-03
- 0.5.2-next.v.202608281122.0 — 2026-08-28
- 0.5.0 — 2026-08-26
- 0.4.0 — 2026-08-12
- 0.3.0 — 2026-07-29
- 0.2.0 — 2026-07-14
- 0.2.1-next.v.202607070741.0 — 2026-07-07

## README

# `@wordpress/video-conversion`

Client-side video conversion package used by `@wordpress/upload-media`. It currently converts animated GIFs to MP4/WebM during media upload.

This package is not used directly. When an animated GIF is uploaded, its frames are decoded using the browser's native `ImageDecoder` API and re-encoded via WebCodecs (`VideoEncoder`) using the [mediabunny](https://github.com/Vanilagy/mediabunny) library as an internal implementation detail. All processing runs inside a Web Worker to keep the main thread responsive.

## Installation

Install the module:

```bash
npm install @wordpress/video-conversion --save
```

## Requirements

-   **WebCodecs support**: the browser must expose `ImageDecoder` and `VideoEncoder` (available in Chromium-based browsers and Safari 16.4+).
-   **Web Workers support**: the browser must support Web Workers.
-   **TypeScript support**: TypeScript consumers require TypeScript 5 or newer.

## API Reference

<!-- START TOKEN(Autogenerated API docs) -->

### cancelOperations

Cancels all ongoing operations for a given item ID.

Cancellation takes effect at async boundaries (waiting for the lock, encoder-support check, decoder completion, between frames).

_Parameters_

-   _id_ `ItemId`: Item ID.

_Returns_

-   `Promise< boolean >`: Whether an operation was cancelled.

### convertGifToVideo

Converts an animated GIF to a video file (MP4 or WebM).

Decodes GIF frames via the browser ImageDecoder (honoring per-frame delays) and re-encodes them with mediabunny / WebCodecs.

Accepts the GIF as a Blob so the bytes are read once, here in the worker, instead of being materialized on the main thread and transferred. An ArrayBuffer is still accepted for direct callers and tests.

_Parameters_

-   _id_ `ItemId`: Item ID.
-   _gifSource_ `ArrayBuffer | Blob`: GIF file as a Blob/File or ArrayBuffer.
-   _outputMimeType_ `string`: Output MIME type ('video/mp4' or 'video/webm').
-   _maxDimensions_ `number`: Optional maximum dimension for downscaling.
-   _maxTotalPixels_ `number`: Optional budget for total decoded pixels (width × height × frame count) beyond which the conversion is rejected with SIZE_LIMIT_ERROR_PREFIX. Defaults to DEFAULT_MAX_TOTAL_PIXELS; `0` disables.

_Returns_

-   `Promise< ArrayBuffer >`: Encoded video buffer.

### DEFAULT_MAX_TOTAL_PIXELS

Default budget for total decoded pixels (width × height × frame count) beyond which conversion is not attempted.

Conversion cost is roughly proportional to the total number of decoded pixels. 300 megapixels approximates what a mid-range machine converts within the ~30s the caller is willing to wait (e.g. a 1920x1080 GIF at ~145 frames); anything larger would likely be abandoned anyway, so it is cheaper to not start. Pass `0` to disable the check.

### SIZE_LIMIT_ERROR_PREFIX

Message prefix for GIFs skipped because they exceed the total-pixel budget.

Starts with UNSUPPORTED_ERROR_PREFIX so existing consumers treat the skip as a graceful fallback (keep the uploaded GIF, no companion video); the longer prefix lets consumers distinguish it, e.g. to log a warning. Like UNSUPPORTED_ERROR_PREFIX, the contract is the message prefix because only the message string survives the worker boundary.

### UNSUPPORTED_ERROR_PREFIX

Message prefix for "unsupported but graceful" outcomes (no WebCodecs, unsupported codec). Consumers detect this prefix and fall back to uploading the original GIF instead of surfacing a hard error.

The contract is the message _prefix_, not the Error type: the worker RPC layer (comctx) serializes a thrown error to its `message` string only - the Error subclass, `name`, and `stack` do not survive the worker boundary.

<!-- END TOKEN(Autogenerated API docs) -->

---
_Source: https://npm.io/package/@wordpress/video-conversion · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
