Skip to content

short-pixel-optimizer/node-short-pixel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

shortpixel

ShortPixel is an image optimization service built to make websites faster with minimal effort. Official website: https://shortpixel.com/.

In practice, ShortPixel helps you shrink heavy images, serve modern formats like WebP/AVIF, and keep visual quality high. Real-world results can go up to 86% image compression, which means faster pages, better UX, and stronger SEO outcomes.

This repository is the Node.js SDK for that product. It gives you both:

  • a simple, abstract DX (optimize, upscale, rescale, backgroundChange, etc.)
  • and low-level, explicit control (fromFile, fromUrl, Source, per-item Meta, polling/retry tuning)

This README is the complete documentation for the current API surface in this repository.

Table of Contents

  1. What this SDK solves
  2. Installation
  3. Quick Start
  4. Mental model: Client + Source + Meta
  5. Abstraction layers
  6. Full client API reference
  7. Supported API parameters
  8. Practical examples (cookbook)
  9. Power User Guide
  10. Errors, retry, debugging
  11. Running tests
  12. Important notes

What this SDK solves

ShortPixel itself focuses on one core goal: keep images looking great while making them much smaller and easier to deliver at scale.

Inside the API, there are two main endpoints:

  • Reducer API: optimizes images from remote URLs.
  • Post-Reducer API: optimizes local files or buffers uploaded as multipart.

This SDK hides transport details, polling, retry strategy, and response normalization, while still giving you full access to API options.

In short:

  • Want explicit control: use fromFile, fromUrl, etc.
  • Want fast and simple DX: use optimize(...) and feature-first helpers (upscale, rescale, backgroundChange, etc).
  • Want advanced control: use Source, inspect lastMetas, tune polling/retries/timeouts.

Installation

npm i @shortpixel-com/shortpixel

After installation, import from shortpixel:

import SHORTPIXEL from "@shortpixel-com/shortpixel";

Runtime requirements

  • Current state: version 1 (v1.x), ESM-only package
  • In your app package.json, you must set:
{
  "type": "module"
}
  • ESM ("type": "module")
  • Modern Node.js (ideally Node 20+)

It may work by not setting type at all, but it's not stable.


Quick Start

import SHORTPIXEL from "@shortpixel-com/shortpixel";

const { ShortPixelClient } = SHORTPIXEL;
const cli = new ShortPixelClient({
  apiKey: process.env.SHORTPIXEL_API_KEY,
});

const src = await cli.upscale("assets/panda.png", 2, {
  lossy: 2,
  convertto: "+webp",
});

const files = await src.downloadTo("./output");
console.log(files);

Desired feature-first style:

const src = await cli.upscale("/path/input.png", 2);
await src.downloadTo("/path/output");

Mental model: Client + Source + Meta

ShortPixelClient

This is the entry point. It can:

  • configure API key and defaults,
  • accept multiple input forms,
  • route to the correct ShortPixel endpoint,
  • expose higher-level abstractions.

Source

Each operation returns a Source.

Source contains:

  • lastMetas: metadata returned by the API for the latest operation,
  • lastResults: input-to-meta mapping,
  • downloadTo(outputDir): downloads optimized outputs locally.

For regular usage, it's recommended to not directly use the Source.

Meta

Each optimized item has metadata with status (Status.Code) and output URLs (LossyURL, LosslessURL, WebP*, AVIF*, etc). Useful for debugging


Abstraction layers

The SDK is intentionally designed with multiple abstraction layers. Use the one that matches your team and use case.

Layer 1: explicit helpers (from*)

Classic and very explicit:

  • fromUrl(url, options)
  • fromUrls(urls, options)
  • fromURLs(urls, options) (alias)
  • fromFile(path, options)
  • fromFiles(pathsOrObjects, options)
  • fromBuffer(buffer, filename, options)
  • fromBuffers(buffersOrObjects, defaultName, options)

Advantages:

  • clear endpoint intent (Reducer vs Post-Reducer)
  • easy to reason about in large codebases

Layer 2: intent-first aliases (optimize*)

Same operations, naming focused on user intent:

  • optimizeUrl, optimizeUrls
  • optimizeFile, optimizeFiles
  • optimizeBuffer, optimizeBuffers

Advantages:

  • more natural naming for most developers

Layer 3: generic dispatcher optimize(input, options)

Pass input, and the SDK routes automatically.

Supported input shapes

  • URL string -> fromUrl
  • local path string -> fromFile
  • Buffer -> fromBuffer
  • array of URLs -> fromUrls
  • array of file paths/entries -> fromFiles
  • array of buffers/entries -> fromBuffers
  • object shapes:
    • { url }, { urls }
    • { file }, { path }, { filename }
    • { buffer, filename? }, { buffers, defaultName? }, { files }

Important rule

Do not mix remote URLs and local paths in the same string array (optimize(["https://...", "./a.png"]) throws).

Layer 4: feature-first helpers

Methods that set feature defaults, then allow full override via options:

  • quality: lossless, lossy, glossy
  • resize/upscale: upscale, rescale, resizeOuter, resizeInner, smartCrop
  • background: backgroundChange, backgroundRemove
  • format: convert
  • metadata/color: keepExif, cmykToRgb
  • workflow: wait, refresh

These methods are intelligent aliases built on top of optimize(...).


Full client API reference

Constructor

new ShortPixelClient({ apiKey, pluginVersion = "NP001", proxy = null })
  • apiKey is required.
  • pluginVersion must be a string with max 5 characters. Although it's optional
  • proxy is optional and can use http:// or https:// proxy URLs.
  • All final outbound image/API requests are forced to https://; http:// targets are rejected with error.

HTTPS security model (important)

HTTPS is mandatory in this SDK for security reasons:

  • protects image/API traffic against interception (confidentiality),
  • prevents payload tampering in transit (integrity),
  • validates the remote host identity via TLS certificates (authenticity).

Behavior details:

  • direct input URLs over http:// are rejected before network calls,
  • output/polling metadata that may come back as http:// from upstream APIs is upgraded to https:// automatically,
  • the SDK never performs final outbound requests over plain HTTP.

Runtime config

cli.set(name, value)

Useful keys:

  • timeout (ms)
  • retries
  • retryDelay (ms)
  • wait
  • convertto
  • proxy
  • poll -> { enabled, interval, maxAttempts }

Important

Please consider increasing the poll interval and maxAttempts if the polling process fails due to timeout. This is required on complex operations like background-removal or smart resizing.

Core helpers

  • fromUrl(url, options)
  • fromUrls(urls, options)
  • fromURLs(urls, options)
  • fromFile(path, options)
  • fromFiles(pathsOrEntries, options)
  • fromBuffer(buffer, filename, options)
  • fromBuffers(buffersOrEntries, defaultName, options)

optimize* aliases

  • optimize(input, options)
  • optimizeUrl(url, options)
  • optimizeUrls(urls, options)
  • optimizeFile(path, options)
  • optimizeFiles(paths, options)
  • optimizeBuffer(buffer, filename, options)
  • optimizeBuffers(buffers, defaultName, options)

Feature-first aliases

  • lossless(input, options) -> lossy: 0
  • lossy(input, options) -> lossy: 1
  • glossy(input, options) -> lossy: 2
  • wait(input, seconds, options) -> wait: seconds
  • upscale(input, factor = 2, options) -> upscale: factor
  • rescale(input, width, height, options) -> resize: 1
  • resizeOuter(input, width, height, options) -> alias of rescale
  • resizeInner(input, width, height, options) -> resize: 3
  • smartCrop(input, width, height, options) -> resize: 4
  • convert(input, convertto, options) -> convertto
  • cmykToRgb(input, enabled = true, options) -> cmyk2rgb
  • keepExif(input, enabled = true, options) -> keep_exif
  • backgroundChange(input, background = 1, options) -> bg_remove
  • backgroundRemove(input, options) -> bg_remove: 1
  • refresh(input, enabled = true, options) -> refresh

See the Official API documentation for more information : https://shortpixel.com/api-docs

Source exposure

const Source = cli.Source(); // Source is a class

Supported API parameters

Any ShortPixel-supported parameter can be passed via options.

Common parameters

Parameter Purpose SDK usage
key API key constructor new ShortPixelClient({ apiKey })
plugin_version client identifier (max 5 chars) constructor pluginVersion
lossy 0=lossless, 1=lossy, 2=glossy options.lossy or lossless/lossy/glossy
wait wait seconds in API call options.wait or wait(...)
upscale 0,2,3,4 options.upscale or upscale(...)
resize 0 none, 1 outer, 3 inner, 4 smart crop options.resize or rescale/resizeInner/smartCrop
resize_width resize width options.resize_width
resize_height resize height options.resize_height
cmyk2rgb CMYK -> RGB conversion options.cmyk2rgb or cmykToRgb(...)
keep_exif preserve EXIF options.keep_exif or keepExif(...)
convertto output conversion (webp/avif/etc) options.convertto or convert(...)
bg_remove remove/change background options.bg_remove or backgroundChange(...)
refresh refetch/re-optimize source options.refresh or refresh(...)
urllist URL list payload handled internally by fromUrl(s)/optimize
paramlist per-URL settings for reducer batch options.paramlist
returndatalist custom payload echoed by API options.returndatalist

Local SDK validations

Before requests are sent, the SDK validates at minimum:

  • pluginVersion max 5 chars
  • wait in [0..30]
  • upscale in {0,2,3,4}
  • if resize > 0, valid dimensions are required

Practical examples (cookbook)

1) Basic local file optimization

const src = await cli.fromFile("assets/panda.png", { lossy: 1 });
await src.downloadTo("./output");

2) User-friendly alias

const src = await cli.optimizeFile("assets/otherImage.png", { lossy: 2 });
await src.downloadTo("./output");

3) Generic optimization without specifying input type

const srcA = await cli.optimize("test/assets/panda-small.png", { lossy: 0 });
const srcB = await cli.optimize("https://images.unsplash.com/photo-1506744038136-46273834b3fb", { lossy: 1 });
const srcC = await cli.optimize(Buffer.from("..."), { filename: "upload.png", lossy: 2 });

4) Upscale

const src = await cli.upscale("test/assets/panda-small.png", 4, {
  lossy: 0,
  keep_exif: 1,
});
await src.downloadTo("test/output-real");

5) Rescale (outer)

const src = await cli.rescale("test/assets/panda-small.png", 1024, 768, {
  convertto: "+avif",
});
await src.downloadTo("test/output-real");

6) Resize inner

const src = await cli.resizeInner("test/assets/panda-small.png", 400, 400, {
  keep_exif: 1,
});
await src.downloadTo("test/output-real");

7) Smart crop

const src = await cli.smartCrop("test/assets/panda-small.png", 300, 200, {
  convertto: "+webp",
});
await src.downloadTo("test/output-real");

8) Background remove / change

Transparent output:

const src = await cli.backgroundRemove("test/assets/panda-small.png", {
  convertto: "+webp",
});
await src.downloadTo("test/output-real");

Solid color + alpha (#rrggbbxx):

// Warning, this might take a while to process
const src = await cli.backgroundChange("test/assets/panda-small.png", "#00ff0080", {
  lossy: 2,
  convertto: "+webp",
});
await src.downloadTo("test/output-real");

Custom background image URL:

const src = await cli.backgroundChange(
  "test/assets/panda-small.png",
  "https://example.com/background.jpg",
  { convertto: "+webp" }
);
await src.downloadTo("test/output-real");

9) Format conversions

Original + WebP:

await cli.convert("test/assets/panda-small.png", "+webp");

WebP + AVIF only (no original optimization):

await cli.convert("test/assets/panda-small.png", "webp|avif");

Original + WebP + AVIF:

await cli.convert("test/assets/panda-small.png", "+webp|+avif");

10) Local file batch

const src = await cli.fromFiles([
  "test/assets/panda-small.png",
  "test/assets/panda-small.png",
], {
  lossy: 1,
  convertto: "+webp",
});

await src.downloadTo("test/output-real");

11) URL batch

const src = await cli.fromUrls([
  "https://images.unsplash.com/photo-1506744038136-46273834b3fb",
  "https://images.unsplash.com/photo-1506744038136-46273834b3fb"
], {
  lossy: 2,
  convertto: "+avif",
});

await src.downloadTo("test/output-real");

12) Buffer batch

const b1 = Buffer.from("...");
const b2 = Buffer.from("...");

const src = await cli.fromBuffers([
  { buffer: b1, filename: "one.png" },
  { buffer: b2, filename: "two.png" },
], "fallback.bin", {
  lossy: 1,
});

await src.downloadTo("test/output-real");

Power User Guide

Use this when you want deep control over runtime behavior, observability, and tuning.

1) Tune global transport settings

cli.set("timeout", 45000);
cli.set("retries", 4);
cli.set("retryDelay", 1000);

2) Tune polling behavior

cli.set("poll", {
  enabled: true,
  interval: 2000,
  maxAttempts: 20,
});

When API responses come back with pending status (Status.Code = 1), the SDK polls until ready (2) or until attempt budget is exhausted.

3) Global default output format

cli.set("convertto", "+webp");

Any call without an explicit options.convertto inherits +webp.

4) Inspect per-item metadata

const src = await cli.fromFile("test/assets/panda-small.png", {
  lossy: 2,
  convertto: "+webp|+avif",
});

for (const m of src.lastMetas || []) {
  console.log("Code:", Number(m?.Status?.Code));
  console.log("Message:", m?.Status?.Message);
  console.log("LossyURL:", m?.LossyURL);
  console.log("WebP:", m?.WebPLossyURL || m?.WebPLosslessURL);
  console.log("AVIF:", m?.AVIFLossyURL || m?.AVIFLosslessURL);
}

5) Run the flow manually with Source

If you need maximum internals control:

const SourceCtor = cli.Source();
const src = new SourceCtor({ filename: "test/assets/panda-small.png" });

src.setOptions({
  lossy: 2,
  upscale: 2,
  convertto: "+webp",
});

await src.postReducer();
console.log(src.lastMetas);

await src.downloadTo("test/output-real");

For URL-based flows, call src.reducer() instead of postReducer().

6) Handle download manually (without downloadTo)

downloadTo is convenient, but you can use metadata URLs directly for custom naming/storage (S3, object stores, CDN pipelines, etc).

CODE IN PROGRESS

7) Override feature defaults intentionally

Feature helpers set defaults, but options has priority:

await cli.lossless("test/assets/panda-small.png", {
  lossy: 2,
});

The call above effectively runs with lossy: 2.


Errors, retry, debugging

The SDK uses typed errors:

  • ShortPixelError
  • ShortPixelAuthError
  • ShortPixelQuotaError
  • ShortPixelTemporaryError
  • ShortPixelInvalidRequestError
  • ShortPixelBatchError

Error objects may include:

  • httpStatus
  • spCode
  • spMessage
  • payload

Recommended handling pattern:

try {
  const src = await cli.fromFile("test/assets/panda-small.png", { upscale: 9 });
  await src.downloadTo("test/output-real");
} catch (err) {
  console.error("name:", err?.name);
  console.error("spCode:", err?.spCode);
  console.error("spMessage:", err?.spMessage);
  console.error("httpStatus:", err?.httpStatus);
  console.error("payload:", err?.payload);
}

ShortPixelBatchError

In batch mode, one or more failed items can raise ShortPixelBatchError, which includes items (index, input, meta/error per item).

Retry behavior

Retry is used for temporary failures (for example 429, 5xx, temporary SP codes). Configure via:

  • retries
  • retryDelay
  • timeout

Running tests

Please install the development dependency jest js before running tests.

Unit tests:

npm test

Real API integration tests (consume ShortPixel credits):

RUN_SHORTPIXEL_REAL=1 SHORTPIXEL_API_KEY="your-key" npm test

Run specific integration groups:

RUN_SHORTPIXEL_REAL=2 SHORTPIXEL_API_KEY="your-key" npm test
RUN_SHORTPIXEL_REAL=3 SHORTPIXEL_API_KEY="your-key" npm test
RUN_SHORTPIXEL_REAL=4 SHORTPIXEL_API_KEY="your-key" npm test
RUN_SHORTPIXEL_REAL=5 SHORTPIXEL_API_KEY="your-key" npm test
RUN_SHORTPIXEL_REAL=6 SHORTPIXEL_API_KEY="your-key" npm test
RUN_SHORTPIXEL_ALL_REAL=1 SHORTPIXEL_API_KEY="your-key" npm test

Important notes

  1. apiKey is required.
  2. pluginVersion must be max 5 characters. (optional)
  3. downloadTo() only works after an optimization call (from*, optimize*, optimize, feature helpers).
  4. In optimize([...]), do not mix URL strings and local path strings.
  5. All feature helpers (upscale, rescale, backgroundChange, etc.) support additional options, so you can combine capabilities in a single call.
  6. Increase poll time if anything breaks and retry.

Official ShortPixel API docs: https://shortpixel.com/api-docs

About

ShortPixel API integration in a node package.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors