Tiny client and CLI for the Purlo image-processing API — resize, convert, compress, and strip metadata in one call. Zero dependencies; works in Node 18+ and modern browsers.
npm install @purlo/cliThe package is @purlo/cli; the installed command is purlo.
Get a free API key (no card) at purlo.dev — or
curl -X POST https://api.purlo.dev/v1/signup -d '{"email":"you@example.com"}'.
import { PurloClient } from '@purlo/cli';
import { readFile, writeFile } from 'node:fs/promises';
const purlo = new PurloClient({ apiKey: process.env.PURLO_API_KEY });
const { data, format, quotaRemaining } = await purlo.process(
{ image: await readFile('photo.jpg'), filename: 'photo.jpg' },
{ resize: { w: 800 }, format: 'webp', quality: 80, strip: true },
);
await writeFile('out.webp', data);
console.log(`got ${format}, ${quotaRemaining} left this month`);Or have Purlo fetch a URL instead of uploading:
const { data } = await purlo.process(
{ url: 'https://example.com/photo.jpg' },
{ resize: { w: 400 }, format: 'webp' },
);Errors throw a PurloError with .status and .code:
import { PurloError } from '@purlo/cli';
try {
await purlo.process({ url }, { format: 'gif' });
} catch (e) {
if (e instanceof PurloError) console.error(e.code, e.status); // 'invalid_operations' 400
}source:{ image, filename }(bytes:Uint8Array/Buffer/Blob) or{ url }.operations:{ resize: { w, h, fit }, format, quality, strip }— see the reference.stripdefaults totrue(removes EXIF/GPS, keeps the ICC colour profile).- Returns
{ data, format, bytes, operations, quotaLimit, quotaRemaining }.
export PURLO_API_KEY=purlo_your_key
purlo process photo.jpg --width 800 --format webp --quality 80 -o out.webp
purlo process --url https://example.com/a.jpg -f webp -o out.webp
cat photo.jpg | purlo process - -w 400 > out.jpgpurlo --help lists every option.
MIT © Axiom Testing Ltd