ProvenPin Install

Pure-JS image resize, crop and thumbnails with Jimp (no Sharp): working versions (tested 2026-10-15)

Create thumbnails with Jimp (no native deps): cover-crop to a square, resize keeping aspect ratio, and re-encode PNG/JPEG buffers, tested with generated images.

passed4 passed · 0 failed2026-10-15 13:30 UTC
Status
passed
Last passed
2026-10-15 13:30 UTC
Tests
4 / 4
Language
TypeScript
Runtime
node v22.23.3
pinned versions3
jimp@1.6.1tsx@4.23.15@types/node@24.19.2
run it
npm install --no-audit --no-fund --ignore-scripts=false
npm test
test environment
node v22.23.3
linux 6.17.0-1022-azure
x64
runner: github-actions 38742087302

The code

Exactly the files that passed. Your agent can pull them with get_recipe("jimp-image-resize") (install), or see them on GitHub.

package.json
{
  "name": "jimp-image-resize",
  "private": true,
  "type": "module",
  "scripts": {
    "test": "node --import tsx --test test/*.test.ts"
  },
  "dependencies": {
    "jimp": "1.6.1"
  },
  "devDependencies": {
    "tsx": "4.23.15",
    "@types/node": "24.19.2"
  }
}
src/thumbs.ts
import { Jimp, JimpMime } from "jimp";

export async function squareThumb(input: Buffer, size = 128) {
  const img = await Jimp.read(input);
  img.cover({ w: size, h: size }); // scale + center-crop
  return img.getBuffer(JimpMime.png);
}

export async function fitWidth(input: Buffer, width: number, quality = 80) {
  const img = await Jimp.read(input);
  if (img.width > width) img.resize({ w: width }); // height follows aspect ratio
  return img.getBuffer(JimpMime.jpeg, { quality });
}

export async function size(buf: Buffer) {
  const img = await Jimp.read(buf);
  return { w: img.width, h: img.height, mime: img.mime };
}
test/thumbs.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { Jimp, JimpMime } from "jimp";
import { fitWidth, size, squareThumb } from "../src/thumbs.ts";

const makePng = (w: number, h: number) => new Jimp({ width: w, height: h, color: 0x1ed67fff }).getBuffer(JimpMime.png);

test("square thumbnail from a wide image", async () => {
  assert.deepEqual(await size(await squareThumb(await makePng(400, 200), 64)), { w: 64, h: 64, mime: "image/png" });
});

test("fit width keeps aspect ratio and outputs jpeg", async () => {
  assert.deepEqual(await size(await fitWidth(await makePng(1000, 500), 250)), { w: 250, h: 125, mime: "image/jpeg" });
});

test("does not upscale small images", async () => {
  assert.equal((await size(await fitWidth(await makePng(100, 50), 250))).w, 100);
});

test("rejects non-images", async () => {
  await assert.rejects(squareThumb(Buffer.from("not an image")));
});

Connect to ProvenPin

Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.

terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp

Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.