Skip to content
Abdulkader Safi edited this page Jul 16, 2026 · 3 revisions

s-img

Short for safi-image. Image editing for Node and Bun, written entirely in TypeScript. No native binaries, no postinstall compile step, no prebuilt platform packages.

import { SImg } from 's-img';

const out = await SImg.fromBuffer(bytes)
  .crop({ x: 200, y: 100, width: 800, height: 600 })
  .rotate(8)
  .maxLongEdge(400)
  .toFormat('jpeg', { quality: 80 })
  .toBuffer();

Start here

Installation Install it from GitHub and check it works.
Getting Started The chain, the pipeline, and the five things worth knowing.
API Reference Every export, what it does, what it throws.
Formats What each format supports, its options, and its quirks.
Previews and Performance The two-pass design, and the coordinate trap.
Errors Every error code and what to do about it.
Architecture How it is built, and why it is built that way.
Contributing Tests, guards, the size budget, how to add a codec.

What it does

  • Reads and writes PNG, JPEG, WebP, GIF, BMP, TIFF.
  • Crop, rotate, flip, resize. Rotation takes arbitrary angles, not just 90° steps.
  • Format conversion and quality control, plus metadata stripping (EXIF, GPS, colour profiles).
  • Previews: decode small and fast, so a slider drag stays inside a frame.

PNG, JPEG, GIF, BMP and TIFF are pure TypeScript and always loaded. WebP is a libwebp WASM module that loads on first use, so you only pay for it if you touch a WebP file.

Why it exists

It is the engine for an Obsidian image editor plugin that currently bundles ImageMagick. That bundle is 7 MB, and Obsidian Sync struggles with binaries that size, so anyone using Sync cannot run the plugin.

Same editing capability, at a fraction of the size, is the whole point:

Size vs ImageMagick
Core (PNG, JPEG, GIF, BMP, TIFF), min+gzip 23.2 KB ~300× smaller
The 150 KB budget it is measured against 150 KB ~47× smaller
The ImageMagick bundle being replaced 7 MB

CI fails the build if the core goes over 150 KB. It currently uses 15.5% of that.

Status

Every feature is built: all six formats read and write, the transforms and the pipeline are done. 567 tests, a Bun parity check, and a size gate on every PR.

Not published to npm yet — install it from GitHub.

Clone this wiki locally