Skip to main content
The dpf engine communicates over standard input and output using newline-delimited JSON. Every job is a single JSON object sent on one line; every response is a single JSON object returned on one line. No framing, headers, or length prefixes are used.
stdin  → {"operation":"resize", ...}\n
stdout ← {"success":true, "operation":"resize", "outputs":[...], "elapsed_ms":42}\n

Job structure

Every job object requires an operation field that identifies the operation to run. All other fields are operation-specific.
{
  "operation": "<operation>",
  ...
}

Available operations

CategoryOperations
Imageresize, crop, rotate, watermark, adjust, quality, srcset, exif, optimize, convert, palette, favicon, sprite, placeholder
Batchbatch
Videovideo_transcode, video_resize, video_trim, video_thumbnail, video_profile, video_metadata
Audioaudio_transcode, audio_trim, audio_normalize, audio_silence_trim

CLI usage modes

dpf supports four ways to submit jobs.

One-shot

Pass a single job as a JSON string argument. The process starts, processes the job, prints one response line, and exits.
dpf process --job '{"operation":"resize","input":"photo.jpg","output_dir":"dist","widths":[320,640,1024]}'

Stdin

Pipe a single job via stdin. Useful in shell scripts and pipelines.
echo '{"operation":"convert","input":"photo.png","output":"photo.webp","format":"webp"}' | dpf

Streaming

Start a persistent process with --stream. dpf reads one JSON line from stdin, writes one JSON line to stdout, and repeats — keeping the process alive across many jobs. This avoids the startup cost of spawning a new process for each operation.
dpf --stream
Streaming mode is recommended for server workloads. It eliminates per-job process spawn overhead and keeps the engine warm, resulting in significantly lower latency at high throughput.

Batch file

Run a file containing one JSON job per line. Jobs execute in parallel.
dpf batch --file jobs.json
jobs.json contains one job per line:
{"operation":"resize","input":"hero.jpg","output_dir":"dist","widths":[320,640,1280]}
{"operation":"optimize","inputs":["icon.png"],"output_dir":"dist"}
{"operation":"convert","input":"banner.png","output":"banner.webp","format":"webp"}

Streaming session example

The following shows a complete interactive streaming session. Each line is written to stdin; each line is read from stdout.
→ {"operation":"resize","input":"photo.jpg","output_dir":"out","widths":[320,640]}
← {"success":true,"operation":"resize","outputs":[{"path":"out/photo-320.jpg","format":"jpeg","width":320,"height":213,"size_bytes":18432},{"path":"out/photo-640.jpg","format":"jpeg","width":640,"height":427,"size_bytes":41984}],"elapsed_ms":38}

→ {"operation":"watermark","input":"photo.jpg","output":"out/photo-wm.jpg","text":"© 2024","position":"bottom-right","opacity":0.8}
← {"success":true,"operation":"watermark","outputs":[{"path":"out/photo-wm.jpg","format":"jpeg","width":1920,"height":1280,"size_bytes":312400}],"elapsed_ms":12}

→ {"operation":"optimize","inputs":["out/photo-320.jpg","out/photo-640.jpg"],"output_dir":"out/opt","level":"lossless"}
← {"success":true,"operation":"optimize","outputs":[{"path":"out/opt/photo-320.jpg","format":"jpeg","width":320,"height":213,"size_bytes":17200},{"path":"out/opt/photo-640.jpg","format":"jpeg","width":640,"height":427,"size_bytes":39100}],"elapsed_ms":55}

The inline field

Any operation that produces image output accepts an optional inline boolean. When set to true, the engine base64-encodes each output and includes it in data_base64 on the corresponding OutputFile object, in addition to writing the file to disk.
{
  "operation": "resize",
  "input": "photo.jpg",
  "output_dir": "out",
  "widths": [320],
  "inline": true
}
Response with inline data:
{
  "success": true,
  "operation": "resize",
  "outputs": [{
    "path": "out/photo-320.jpg",
    "format": "jpeg",
    "width": 320,
    "height": 213,
    "size_bytes": 18432,
    "data_base64": "iVBORw0KGgoAAAANSUhEUgAAAAE..."
  }],
  "elapsed_ms": 41
}
This is useful when you want to consume the image in memory (for example, returning it from an HTTP handler) without reading from disk.

Build docs developers (and LLMs) love