npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

e621-thumbnailer

v2.0.0

Published

Generate thumbnails for e621 videos.

Downloads

83

Readme

e621-thumbnailer

Generate image and animated thumbnails from e621 videos.

Note: thumbnail generation takes 5–20 seconds depending on input size and type. Pre-generate in bulk rather than on demand.

Requirements

  • Node.js ≥ 20.19.0
  • ffmpeg and ffprobe — either install ffmpeg-static and ffprobe-static as dependencies, or ensure the binaries are in PATH
  • gifsicle in PATH — optional, enables GIF optimisation

Installation

npm install e621-thumbnailer

# optional: bundled ffmpeg/ffprobe (no system install required)
npm install ffmpeg-static ffprobe-static

Library usage

import thumbnail from "e621-thumbnailer";

The default export is an async function:

thumbnail(input: string | number, options?: ThumbnailOptions): Promise<Thumbnail>

input accepts:

| Value | Resolved as | |-------|-------------| | Number | e621 post ID — fetched via the API | | 32-char hex string | MD5 hash — post resolved via the API | | String starting with http:// or https:// | Direct URL, downloaded | | Any other string | Local file path |

The returned Thumbnail object has three methods:

// Copy the file to a permanent location
await thumb.save("./out.png");

// Get the raw bytes without saving to disk
const buf: Buffer = await thumb.toBuffer();

// Delete the underlying temp file (called automatically on process exit)
await thumb.delete();

Examples

import thumbnail from "e621-thumbnailer";

// PNG from a post ID
const thumb = await thumbnail(4505261);
await thumb.save("thumb.png");
await thumb.delete();

// JPEG from an MD5 hash
const thumb = await thumbnail("a51d55b12e7a16a37253783e52c4ec21", { format: "jpg" });
const buf = await thumb.toBuffer(); // use as buffer instead of saving

// Animated GIF from a URL
const thumb = await thumbnail("https://static1.e621.net/data/3c/6c/3c6c18c18c096b5a7ff2fa3bdecf3a63.webm", {
    type: "animated",
    length: 3,
    gifOptimizationLevel: 2,
});
await thumb.save("clip.gif");
await thumb.delete();

// Animated WebP from a local file
const thumb = await thumbnail("./video.webm", {
    type: "animated",
    format: "webp",
});
await thumb.save("clip.webp");
await thumb.delete();

Options

Image options (type?: "image")

| Option | Type | Default | Description | |--------|------|---------|-------------| | format | "png" \| "jpg" \| "webp" | "png" | Output format | | width | number | 0 | Scale width in pixels; 0 = original size | | jpegQuality | number | 2 | JPEG quality (1–31, lower = better) | | webpQuality | number | 85 | WebP quality (0–100) |

Animated options (type: "animated")

| Option | Type | Default | Description | |--------|------|---------|-------------| | format | "gif" \| "webp" | "gif" | Output format | | length | number | 2.5 | Clip duration in seconds | | fps | number | 15 | Frames per second | | width | number | 480 | Output width in pixels | | colors | number | 128 | GIF palette size (2–256) | | gifOptimizationLevel | 0 \| 1 \| 2 \| 3 | 0 | Gifsicle optimisation level; 0 = disabled | | quality | number | 75 | WebP quality (0–100) |

Shared options (both types)

| Option | Type | Default | Description | |--------|------|---------|-------------| | ffmpegPath | string | auto | Path to ffmpeg binary | | ffprobePath | string | auto | Path to ffprobe binary |

CLI usage

e621-thumbnailer <input> [options]

input accepts the same values as the library function (post ID, MD5, URL, or file path).

# PNG thumbnail for post 4505261 → ./thumbnail.png
e621-thumbnailer 4505261

# Animated GIF with optimisation
e621-thumbnailer 4505261 -t animated --gif-optimize 2 -o clip.gif

# Animated WebP from an MD5 hash
e621-thumbnailer a51d55b12e7a16a37253783e52c4ec21 -t animated -f webp -o clip.webp

# JPEG from a local file at a specific width
e621-thumbnailer ./video.webm -f jpg -w 640 -o thumb.jpg

# Write PNG to stdout and pipe into another tool
e621-thumbnailer 4505261 -o - | display

CLI flags

| Flag | Default | Description | |------|---------|-------------| | -o, --output <path> | ./thumbnail.<fmt> | Output file path; use - to write to stdout | | -t, --type <type> | image | image or animated | | -f, --format <fmt> | png / gif | Format (see options tables above) | | -w, --width <px> | 0 / 480 | Scale width | | --length <s> | 2.5 | Animated clip duration | | --fps <n> | 15 | Animated fps | | --colors <n> | 128 | GIF palette size | | --quality <n> | 75 | Animated WebP quality | | --webp-quality <n> | 85 | Image WebP quality | | --jpeg-quality <n> | 2 | JPEG quality (1–31) | | --gif-optimize <0-3> | 0 | Gifsicle optimisation level | | --ffmpeg <path> | auto | Path to ffmpeg | | --ffprobe <path> | auto | Path to ffprobe | | -h, --help | | Print help and exit |

A man page is also installed: man e621-thumbnailer.

GIF file size

The default settings apply several techniques to keep GIFs small:

  • Single-pass palettepalettegen and paletteuse run in one ffmpeg filtergraph, avoiding a separate palette file
  • Bayer dithering with diff_mode=rectangle — only changed regions are re-encoded per frame
  • 480 px width, 15 fps — reducing these two values has the largest impact on size
  • 128-colour palette — half the GIF maximum of 256

A 2.5-second clip typically comes out at 3–8 MB versus 40+ MB with default ffmpeg settings. For the smallest possible output, use format: "webp" — animated WebP achieves comparable quality at roughly a quarter of the GIF size.