npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

edgesharp

v0.1.4

Published

Next.js custom image loader for edgesharp — points <Image> at a Cloudflare Worker that does the optimization on Workers + R2.

Downloads

626

Readme

edgesharp

Cloudflare-native image optimization for Next.js. A drop-in replacement for the default /_next/image endpoint, running on Cloudflare Workers with Zig WASM SIMD for JPEG/PNG/WebP and a vendored libavif for native AVIF.

Live playground · Documentation

Deploy to Cloudflare

What it is

  • One change in next.config.mjs and every <Image> in your app routes through Cloudflare Workers instead of the default Next.js image optimizer.
  • 3-tier cache: Cache API → R2 → WASM transform. R2 egress is free, so the hot path is bandwidth-free.
  • One Worker, one bundle. src/worker.ts always ships JPEG / PNG / WebP plus native AVIF via vendored libavif. ~838 KB gzip. Needs Workers Paid ($5/month per Cloudflare account); Workers Free is not supported (10 ms CPU/request, no Durable Objects). A single DISABLED_FORMATS env var (a comma-separated list, recognized values: jpeg, png, webp, avif, gif, svg) lets you drop any output format at runtime, flip it in the Cloudflare dashboard, no redeploy. DISABLED_FORMATS="avif" is the typical setting since AVIF encode is the most CPU-expensive.

Install

In your Next.js project:

pnpm add edgesharp
// next.config.mjs
export default {
  images: {
    loader: "custom",
    loaderFile: "./node_modules/edgesharp/dist/loader.js",
  },
};

Then point the loader at your deployed Worker URL via env var:

# .env.local (or your hosting platform's env config)
NEXT_PUBLIC_IMAGEMODE_URL=https://your-worker.workers.dev

<Image> components stay exactly as written, srcSet, sizes, blur previews, priority, fill mode all unchanged.

Prefer not to use an env var? Make a tiny custom loader file:

// app/edgesharp-loader.js
import { createLoader } from "edgesharp/loader";
export default createLoader({ url: "https://your-worker.workers.dev" });

…and point loaderFile at that file instead.

Deploy your own

The button above takes you through Cloudflare's flow, fork this repo to your GitHub, connect Workers Builds, auto-create the R2 bucket and Durable Object, deploy. The pre-built WASM binaries are committed to the repo so the build doesn't need Zig.

After your first deploy, change a few things in your fork's wrangler.json:

  • ORIGIN: your Next.js app's origin URL. Path-relative ?url=/foo.jpg parameters are fetched from here.
  • ALLOWED_ORIGINS: by default "*" (so the demo's "paste any URL" playground works). Narrow this to a curated list of image hosts before putting the Worker in front of real traffic. Pair with Cloudflare Rate Limiting and Bot Fight Mode if it's publicly reachable.
  • Optional: DISABLED_FORMATS in the Cloudflare dashboard. Comma-separated list of formats to drop (recognized: jpeg, png, webp, avif, gif, svg). For transformed outputs (jpeg/png/webp/avif), the negotiator skips disabled formats and picks the next-best one the browser accepts. For passthrough inputs (gif animation / svg), disabling rejects the source with 415. If every format the browser accepts is disabled, the Worker returns 415. DISABLED_FORMATS="avif" is the typical setting for watching CPU spend; DISABLED_FORMATS="svg,gif" refuses passthrough inputs.

Local development

pnpm install
pnpm run build       # builds WASM + TS + demo
pnpm run dev         # wrangler dev on :8787 (single bundle, libavif included)

The WASM build needs Zig 0.16 locally if you change anything under wasm/src/. The pre-built artifacts in src/wasm/ and wasm/vendor/ ship with the repo so deploy-button users don't need Zig.

Costs

  • Cloudflare Workers Paid - $5/month per Cloudflare account, 10M requests/month included, $0.30 per million after. Workers Free is not supported.
  • R2 storage: $0.015 / GB-month; egress is free.
  • No per-transform fees. After the first cold transform of each (url, width, quality, format), repeat requests serve from R2 with free egress. CPU cost is per distinct variant, not per request, so crawler traffic on URLs you've already served doesn't scale costs the way per-transform pricing does. Compare to Vercel image optimization pricing.

Limitations

The decoder is built for the formats Next.js's <Image> actually serves - not feature-parity with Sharp. Currently unsupported:

  • CMYK JPEGs: print colorspace, rare on the web. Re-export as RGB.
  • 16-bit PNG: uncommon for web; we decode 8-bit only.
  • BMP, ICO: design choice, rare on the web.
  • TIFF, HEIC, RAW (CR2/NEF/ARW/...): out of scope; these are professional formats that don't appear in <Image> source files.

What we do handle that the Next.js default also handles: baseline + progressive JPEGs, PNGs, WebP (still and animated passthrough), GIF (still and animated passthrough), AVIF, SVG (passthrough with restrictive CSP). See Compatibility for the full side-by-side.

Companion Worker: edgesharp-og

The same repo includes og/, a separate Worker that generates social share images (OpenGraph, Twitter, square thumbnails) from a meta tag. Independent deploy, independent bundle (~1.6 MB gzip), independent R2 bucket. Same $5/mo Workers Paid per-account covers both.

<meta property="og:image" content="https://og.example.com/og/">
<meta name="twitter:image" content="https://og.example.com/x/">

The Worker reads the Referer header to know which page is being shared, fetches that page’s <head>, substitutes its <meta> tags into a bundled HTML template, and renders a PNG. Templates live in og/src/templates/ — fork the repo, edit the HTML, push to git; Workers Builds redeploys.

Deploy edgesharp-og to Cloudflare

See og/README.md for the full URL contract, allowed-origin setup, and template authoring guide.

Documentation

Full docs at https://edgesharp.teamchong.net.

License

MIT, see LICENSE.