Skip to content

Images

Source: src/Cloudflare/Images/Images.ts

A Cloudflare Images binding for image transformation and manipulation inside Workers.

The Effect-native interface (Cloudflare.Images.bind(...)) returns an ImagesClient whose methods take Effect Stream.Stream<Uint8Array> inputs and return Effects — info, input(...).transform(...) .draw(...).output(...). The runtime conversion to Cloudflare’s ReadableStream is handled internally.

Read image format and dimensions from the request body

import { HttpServerRequest } from "effect/unstable/http/HttpServerRequest";
Cloudflare.Worker("ImageWorker", { main: import.meta.filename },
Effect.gen(function* () {
// Attaches the binding to this Worker AND returns the runtime client.
const images = yield* Cloudflare.Images({ name: "PIPELINE" });
return {
fetch: Effect.gen(function* () {
const request = yield* HttpServerRequest;
// request.stream is Stream.Stream<Uint8Array>
const info = yield* images.info(request.stream);
return yield* HttpServerResponse.json(info);
}),
};
}).pipe(Effect.provide(Cloudflare.ImagesBindingLive)),
);

Transform an image — chainable pipeline, single Effect at the end

const result = yield* (yield* images.input(request.stream))
.transform({ width: 128 })
.output({ format: "image/jpeg" });
const response = yield* result.response;
export const Worker = Cloudflare.Worker("Worker", {
main: "./src/worker.ts",
env: { MEDIA: Cloudflare.Images({ name: "PIPELINE" }) },
});
export type WorkerEnv = Cloudflare.InferEnv<typeof Worker>;
// { MEDIA: ImagesBinding }

Inside the Worker, the raw Cloudflare runtime binding is reachable via client.raw if you need to call info() / input() directly with async/await. The Effect-native interface is preferred — it returns tagged ImagesErrors, threads WorkerEnvironment, and lets you stream Effect Stream<Uint8Array> sources without manual conversion.