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

@magnaboy/r2-client

v0.0.2

Published

Cloudflare R2 client with uploads, retries, signed URLs, and CORS management.

Readme

@magnaboy/r2-client

Node.js client for Cloudflare R2. Supports paginated listing, concurrent uploads and deletes with retries, signed upload URLs, object metadata, and bucket CORS.

Import R2Client from '@magnaboy/r2-client'. Configure accountId, accessKeyId, secretAccessKey, and bucketName in the constructor.

Requires Node.js 25+. Concurrency defaults to 15 and retries to 3. Folder and file name are concatenated directly. Include a trailing slash in the folder when needed.

Upload and delete return false and emit an error event after retries fail. List errors emit an error event and throw. Attach an error listener to handle failures.

Throwing object operations

R2ObjectStore provides head, getBuffer, getText, snapshot, put, putFile, and destroy. Configure endpoint, bucket, accessKeyId, and secretAccessKey. Call destroy() when finished to close SDK connections.

head and getText return null only for HTTP 404. snapshot returns { text, etag }, or two nulls for an absent object. Signed GETs request identity encoding; snapshot rejects missing or weak ETags. Buffer/text reads retain the complete object in memory.

Writes accept contentType, cacheControl, signal, and optional expectedEtag: omit the property for unconditional writes, pass null to create only, or pass the exact strong quoted ETag to replace a matching object. HTTP errors throw ObjectStoreError with a status and original cause; 412 never becomes an unconditional retry. If a response is lost after the server commits, a retry can return 412: re-read and reconcile at the application level. Do not assume the first write failed or blindly overwrite the object.

putFile streams a file and reopens it on each attempt, hashing its payload before upload. Keep the file unchanged until completion. Defaults are three total attempts, exponential delays starting at 500 ms, and one 120-second deadline across hashing, requests, body reads and retries. Configure attempts, retryDelayMs, and timeoutMs; each operation also accepts an AbortSignal. SDK retries are disabled so the object API owns the attempt budget. Only temporary HTTP and selected transport failures retry. Invalid arguments, permission failures and conflicts do not retry. The older boolean-returning R2Client upload API remains available unchanged.

pnpm test:unit tests the object API against a local HTTP server with fake credentials. The coverage configuration covers the new R2ObjectStore API; legacy R2Client coverage is not claimed.

Application storage port

createR2ObjectStore({ accountId, accessKeyId, secretAccessKey, bucketName, publicUrl }) returns an ObjectStore with throwing put, delete, head, getBytes, signedUploadUrl, and publicUrl operations. Call destroy() when finished. Transfers share a concurrency limit (15 by default) and use the throwing object API's retry rules. retries counts retries after the first attempt (default 3). An optional endpoint supports other S3 services and local tests.

head returns { size, contentType } or null for 404. getBytes returns bytes or null for 404. Permission errors throw. Signed uploads default to 300 seconds, accept a lifetime of 1 to 604800 seconds, and can bind a nonnegative content length. publicUrl joins the configured base and key, preserving the application's key convention.

The ObjectStore port and input/result types are also exported from @magnaboy/r2-client/object-store, which has no Node or AWS imports. R2ObjectStore exposes the added operations directly as headObject, getBytes, delete, and signedUploadUrl. Its existing head return shape is unchanged.