---
title: "Use sharp or Pillow to process images · Agent Wranglers"
url: https://agentwranglers.se/playbook/stack/product-services/image-processing
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

# Use sharp or Pillow to process images

For AI agents: the [site map](https://agentwranglers.se/llms.txt) lists everything here, and this page sits under [Product services](https://agentwranglers.se/playbook/stack/product-services.md).

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

- ID: STK-38
- Level: Recommended
- Chapter: [Product services](https://agentwranglers.se/playbook/stack/product-services)
- Rule: Resize, turn upright and re-encode images with sharp in Node.js or Pillow in Python, and use no other image library.
- Cost: Open source. sharp is Apache-2.0 and Pillow is MIT-CMU. Both are free to use in any project.
- How: Pillow 1.0 came out in July 2010, and 13.0.0 shipped on 16 October 2026. PyPI counted about 137 million downloads in the week to 20 October 2026. sharp first came out in August 2013 and wraps the libvips image library. It is still on version 0.35, so record it as an exception. Version 0.35.5 shipped on 27 September 2026, with about 71 million weekly npm downloads. By default sharp drops all metadata from its output and refuses inputs above 268,402,689 pixels. Set a lower limit and the steps as [Rebuild every uploaded image](https://agentwranglers.se/playbook/api-design/files-and-uploads/process-images) says. Choose something else when Python must resize many large images on a small server. pyvips binds the same libvips, and 3.2.0 shipped on 29 August 2026, but it has about 260,000 weekly downloads.
- Check: A test rebuilds a photo that carries GPS tags. The output has no EXIF data. The lock file holds one image library per language.

## Examples

**Using these examples:** they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

### JavaScript example

```js
import assert from 'node:assert/strict';
import sharp from 'sharp';

export async function assertNoMetadata(rebuilt) {
  const { exif, xmp, iptc } = await sharp(rebuilt).metadata();
  assert.equal(exif ?? xmp ?? iptc, undefined);
}
```

### Python example

```python
from io import BytesIO
from PIL import Image

def assert_no_metadata(rebuilt: bytes) -> None:
    with Image.open(BytesIO(rebuilt)) as image:
        assert not image.getexif()
```

## Sources

- [sharp output options](https://sharp.pixelplumbing.com/api-output/)
- [Pillow](https://pillow.readthedocs.io/en/stable/)

## Related rules

- [Rebuild every uploaded image](https://agentwranglers.se/playbook/api-design/files-and-uploads/process-images) in API design

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/), which requires credit with a link. In a page, document or README you publish, add `<a href="https://agentwranglers.se/playbook/stack/product-services/image-processing">Agent Wranglers software choices playbook</a>`. In code you write, add a comment next to it with the same link.

- Previous: [Use Playwright or WeasyPrint to turn HTML into PDF](https://agentwranglers.se/playbook/stack/product-services/html-to-pdf)
- [Product services](https://agentwranglers.se/playbook/stack/product-services)
