node-ffmpeg

FFmpeg, without the shell games.

Media pipelines.
Typed end to end.

A modern Node.js interface for probing, transforming, and exporting media—with native promises, safe arguments, and zero runtime dependencies.

Start building
transcode.ts Node 24
import ffmpeg from 'ffmpeg'

const video = await ffmpeg(input)

video.on('progress', ({ percent }) => {
  console.log(`${percent.toFixed(1)}%`)
})

await video
  .setVideoCodec('libx264')
  .setVideoSize('1280x?', true)
  .save(output)
encoding72.4%
00:01:422.3× realtime
01 / PRINCIPLE

One focused abstraction.

Your arguments stay arguments.
Your media stays under control.

No command interpolation. No bundled binary. No legacy promise library. Just a precise TypeScript API over the FFmpeg tools you already trust.

One fluent pipeline

From source to artifact,
without losing the plot.

01

Inspect

Structured ffprobe JSON, normalized into a stable typed model.

video.metadata
02

Compose

Chain codecs, dimensions, metadata, filters, and additional inputs.

.setVideoSize()
03

Observe

Track start, stderr, progress, completion, aborts, and failures.

.on('progress')
04

Deliver

Export safely through process arguments—never through a shell string.

await .save()
ZERO

runtime dependencies

01

Native Promise and AbortSignal

02

ESM and CommonJS

03

First-party TypeScript types

04

Progress and lifecycle events

05

Remote protocol inputs

A modern core, a familiar surface

Old code keeps moving.
New code feels native.

Modernconst video = await create(input)
Classicconst video = await new ffmpeg(input)
Callbacknew ffmpeg(input, (error, video) => {})

The next frame is yours

Build the pipeline.
Ship the media.