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

@piwit/cloudfront-signed-fetch

v1.0.0

Published

Fetch wrapper that adds x-amz-content-sha256 header for CloudFront + Lambda Function URL payload integrity

Readme

cloudfront-signed-fetch

A drop-in fetch() wrapper that computes the x-amz-content-sha256 header required for POST/PUT/PATCH requests through CloudFront OAC to Lambda Function URLs.

Problem

When CloudFront uses OAC (Origin Access Control) to sign requests to Lambda Function URLs with SigV4, it does not compute the SHA-256 hash of the request body. Lambda Function URLs don't support unsigned payloads — they require the x-amz-content-sha256 header to contain the actual hash of the body.

From the AWS documentation:

If you use PUT or POST methods with your Lambda function URL, your users must compute the SHA256 of the body and include the payload hash value of the request body in the x-amz-content-sha256 header when sending the request to CloudFront. Lambda doesn't support unsigned payloads.

Without this header, POST/PUT requests will fail. CloudFront passes the header through to the origin, but the responsibility is entirely on the caller.

Common workarounds involve computing the hash server-side (e.g., Lambda@Edge on the origin request), but Lambda@Edge truncates request bodies at ~1 MB while Lambda Function URLs accept up to 6 MB — creating a gap where larger payloads cannot be hashed at the edge.

Install

npm install cloudfront-signed-fetch

Usage

import { signedFetch } from "cloudfront-signed-fetch";

// Use exactly like fetch() — the header is added automatically for write methods
const res = await signedFetch("https://d111111abcdef8.cloudfront.net/api", {
  method: "POST",
  body: JSON.stringify({ hello: "world" }),
  headers: { "Content-Type": "application/json" },
});

Behavior

  • POST, PUT, PATCH — computes SHA-256 of the body (or empty hash if no body) and sets x-amz-content-sha256
  • GET, HEAD, DELETE — no header added, request passes through unchanged
  • All BodyInit types are supported: string, ArrayBuffer, Blob, FormData, URLSearchParams, ReadableStream, and typed arrays
  • Uses the Web Crypto API (crypto.subtle.digest) — works in all modern browsers and Web Workers

Notes

  • This does not replace SigV4 signing — CloudFront OAC handles that. This library only provides the payload hash that Lambda requires.
  • When your frontend is served from the same CloudFront distribution as the API (recommended), requests are same-origin and the custom header does not trigger CORS preflights.
  • If making cross-origin requests, the origin must include x-amz-content-sha256 in Access-Control-Allow-Headers.

E2E testing

The e2e/ directory contains a CDK stack and Playwright tests that validate the library against a real CloudFront + Lambda Function URL deployment.

npm run e2e:deploy   # deploy CDK stack (CloudFront + Lambda + OAC)
npm run e2e:test     # run Playwright tests against the distribution
npm run e2e:destroy  # tear down the stack
npm run e2e          # all three in sequence

The test page is served directly from a CloudFront Function — no S3 bucket needed. The built signedFetch bundle is inlined in the HTML.