# modern-gif

> Fastest GIF decoder / encoder. using TypeScript.

Latest version **2.1.0** (published 2026-04-16) · MIT license · 0 weekly downloads

## Install

```sh
npm install modern-gif
pnpm add modern-gif
yarn add modern-gif
bun add modern-gif
```

## Health

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

Positive: has types; esm support; no vulnerabilities; has provenance; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 2.1.0 |
| Published | 2026-04-16 |
| First published | 2023-02-09 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 163.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 63 |
| Author | wxm |
| Maintainers | wengxiangmin |
| Keywords | gif, encoder, decoder |

## Links

- npm: https://www.npmjs.com/package/modern-gif
- Repository: https://github.com/qq15725/modern-gif
- Issues: https://github.com/qq15725/modern-gif/issues
- npm.io page: https://npm.io/package/modern-gif

## Dependencies (1)

- [modern-palette](https://npm.io/package/modern-palette.md) ^2.0.0

## Alternatives

- [flatbuffers](https://npm.io/package/flatbuffers.md) — 6.0M weekly downloads
- [jwt-simple](https://npm.io/package/jwt-simple.md) — 259.5K weekly downloads
- [@exodus/patch-broken-hermes-typed-arrays](https://npm.io/package/@exodus/patch-broken-hermes-typed-arrays.md) — 28.5K weekly downloads
- [@native-to-anchor/buffer-layout](https://npm.io/package/@native-to-anchor/buffer-layout.md) — 12.2K weekly downloads
- [binary-parser-encoder](https://npm.io/package/binary-parser-encoder.md) — 5.3K weekly downloads

## Recent versions

- 2.1.0 (latest) — 2026-04-16
- 2.0.4 — 2024-12-25
- 2.0.3 — 2024-03-27
- 2.0.2 — 2024-01-10
- 2.0.1 — 2024-01-10
- 2.0.0 — 2024-01-10
- 1.1.10 — 2023-10-23
- 1.1.9 — 2023-10-11
- 1.1.8 — 2023-08-24
- 1.1.7 — 2023-08-21
- 1.1.6 — 2023-08-11
- 1.1.5 — 2023-06-30
- 1.1.4 — 2023-05-25
- 1.1.3 — 2023-05-18
- 1.1.2 — 2023-05-18
- … 21 more at https://npm.io/package/modern-gif/versions

## README

<h1 align="center">modern-gif</h1>

<p align="center">
  <a href="https://unpkg.com/modern-gif">
    <img src="https://img.shields.io/bundlephobia/minzip/modern-gif" alt="Minzip">
  </a>
  <a href="https://www.npmjs.com/package/modern-gif">
    <img src="https://img.shields.io/npm/v/modern-gif.svg" alt="Version">
  </a>
  <a href="https://www.npmjs.com/package/modern-gif">
    <img src="https://img.shields.io/npm/dm/modern-gif" alt="Downloads">
  </a>
  <a href="https://github.com/qq15725/modern-gif/issues">
    <img src="https://img.shields.io/github/issues/qq15725/modern-gif" alt="Issues">
  </a>
  <a href="https://github.com/qq15725/modern-gif/blob/main/LICENSE">
    <img src="https://img.shields.io/npm/l/modern-gif.svg" alt="License">
  </a>
</p>

## Features

- ⚡️ Encode, Decode

- 🎨 Set max colors(2 - 255)

- 🦄️ Compression size

- ☁️️ Web Worker

- 🦾 TypeScript

## Install

```sh
npm i modern-gif
```

## Usage

```ts
import { encode } from 'modern-gif'
// import the workerUrl through Vite
import workerUrl from 'modern-gif/worker?url'

const output = await encode({
  // workerUrl is optional
  workerUrl,
  width: 200,
  height: 200,
  frames: [
    // CanvasImageSource | BufferSource | string
    { data: '/example1.png', delay: 100 },
    { data: '/example2.png', delay: 100 }
  ],
})

const blob = new Blob([output], { type: 'image/gif' })
window.open(URL.createObjectURL(blob))
```

<details>
<summary>Decode</summary><br>

```ts
import { decode, decodeFrames } from 'modern-gif'
import workerUrl from 'modern-gif/worker?url'

const buffer = await window.fetch('/test.gif')
  .then(res => res.arrayBuffer())

// GIF file format data without image data
const gif = decode(buffer)
console.log(gif)

// Image data for all frames (workerUrl is optional)
const frames = await decodeFrames(buffer, { workerUrl })
frames.forEach((frame) => {
  const canvas = document.createElement('canvas')
  canvas.width = frame.width
  canvas.height = frame.height
  canvas.getContext('2d').putImageData(
    new ImageData(frame.data, frame.width, frame.height),
    0,
    0,
  )
  document.body.append(canvas)
})
```

<br></details>

<details>
<summary>Compression size</summary><br>

It is easy to compress a gif by encoding and decoding

```ts
import { decode, decodeFrames, encode } from 'modern-gif'
// import the workerUrl through Vite
import workerUrl from 'modern-gif/worker?url'

const buffer = await window.fetch('/test.gif')
  .then(res => res.arrayBuffer())

const gif = decode(buffer)
// workerUrl is optional
const frames = await decodeFrames(buffer, { workerUrl })
const output = await encode({
  // workerUrl is optional
  workerUrl,
  width: gif.width,
  height: gif.height,
  frames,
  // lossy compression 2 - 255
  maxColors: 255,
})

const blob = new Blob([output], { type: 'image/gif' })
window.open(URL.createObjectURL(blob))
```

<br></details>

<details>
<summary>CDN</summary><br>

```html
<script src="https://unpkg.com/modern-gif"></script>
<script>
  modernGif.encode({
    width: 200, height: 200,
    frames: [
      // CanvasImageSource | BufferSource | string
      { data: '/example1.png', delay: 100 },
      { data: '/example2.png', delay: 100 }
    ],
  }).then(output => {
    const blob = new Blob([output], { type: 'image/gif' })
    const link = document.createElement('a')
    link.download = 'screenshot.png'
    link.href = URL.createObjectURL(blob)
    link.click()
  })
</script>
```

<br></details>

## Types

See the [types.ts](src/types.ts)

## Encode Options

See the [options.ts](src/options.ts)

## Specifications

[GIF89a Spec](https://www.w3.org/Graphics/GIF/spec-gif89a.txt)

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