Skip to content
Image KB Reducer
Esc
↑↓navigate↵open⌘Jpreview
On this page

Install

@imagekbreducer/image-core -- the engine behind the website, the CLI, and the HTTP API.

npm install @imagekbreducer/image-core

This is the same package the CLI (imagekbreducer) depends on and the website (imagekbreducer.com) is built on — not a reimplementation, the actual engine. Per the project’s own framing: 50 KB or less, at the highest quality possible — never exactly 50.000 KB.

Host-agnostic core, three backends

The root import (@imagekbreducer/image-core) has zero DOM and zero node:* dependency — it’s just the job model, inspect(), and the target-size search. Running a job needs a PixelBackend too, and which one you use depends on where your code runs:

import { nodeBackend } from "@imagekbreducer/image-core/node"        // Node
import { canvasBackend } from "@imagekbreducer/image-core/browser"   // browser tab
import { createWasmBackend } from "@imagekbreducer/image-core/wasm"  // Cloudflare Worker, or any host that supplies its own compiled wasm

See Backends for what each one needs from its host.

A minimal Node example

import { readFile } from "node:fs/promises"
import { runJob, inspect, compressJob } from "@imagekbreducer/image-core"
import { nodeBackend } from "@imagekbreducer/image-core/node"

const bytes = await readFile("photo.jpg")
const result = await runJob(
  compressJob(inspect(bytes), { targetBytes: 50 * 1024 }),
  { file: bytes, backend: nodeBackend() },
)

if (!result.ok) throw new Error(result.error.message) // see /library/give-up-codes
const compressed = result.image.data // Uint8Array, at or under 50 * 1024 bytes

Continue to Run a job for the full recipe layer and what JobResult carries either way.

Supported subpaths

package.json technically exports many more paths than this — every internal module apps/web happens to import directly inside this same monorepo. Only the ones below are a stable, published surface with semver behind them; anything else can change shape without a major version bump, even though it’s technically resolvable.

Subpath What it’s for
. runJob, inspect, compressJob/resizeJob/convertJob/cropJob/rotateJob and the rest of the job-recipe layer — the job’s types (ImageJob, JobResult, SourceInfo, Suggestion, Warning), ImageCoreError/ErrorCode, and the unit helpers (parseByteSize, formatBytes, resultFileName) all live on this ONE root import, not on separate subpaths. Host-agnostic: no DOM, no node:*.
./wasm The pure-wasm PixelBackend and its wiring, for a host that supplies its own compiled WebAssembly.Modules (a Cloudflare Worker’s import mod from "./x.wasm").
./node nodeBackend() — the wasm backend wired to Node’s filesystem. A Node process needs nothing beyond import.
./browser canvasBackend, getCapabilities, createWorkerClient, createInlineClient, supportsModuleWorker, warmup — everything a browser page needs to run the engine on its own thread or hand work to a worker.
./testing Test doubles (a seeded EncodeProbe and friends), used to property-test the target-size search without a real encoder. Test fixtures, not a stable API — can change shape without a major version bump.
./fixtures/photo Deterministic pixel generation (photoPixels), shared by this package’s and the CLI’s own tests. Same caveat as ./testing.

Every example on this page and the following pages therefore imports job builders, types, and error helpers from the bare package specifier (@imagekbreducer/image-core), and only reaches for a subpath to get a backend (./node, ./browser, ./wasm).

Was this page helpful?