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

@beignet/provider-storage-vercel-blob

v0.0.40

Published

Vercel Blob object storage provider for Beignet

Readme

@beignet/provider-storage-vercel-blob

Vercel Blob object storage provider for Beignet

[!CAUTION] Beignet is experimental alpha software. The 0.0.x package line is for early evaluation, and APIs may change between releases while the framework settles.

This package adapts Vercel Blob to Beignet's StoragePort, so apps deployed on Vercel get durable object storage without hand-writing an adapter.

createVercelBlobStorageProvider(...) returns the stable VercelBlobStorageProvider type. VercelBlobConfig describes its validated config; the Zod schema remains internal.

Install

bun add @beignet/provider-storage-vercel-blob @vercel/blob

Or scaffold everything — dependencies, provider wiring, ports, env example, and setup notes — with the CLI preset:

bun beignet provider add storage-vercel-blob

Provider setup

// server/providers.ts
import { createVercelBlobStorageProvider } from "@beignet/provider-storage-vercel-blob";

export const providers = [
  // ...
  createVercelBlobStorageProvider(),
] as const;

The provider contributes ports.storage (the standard Beignet StoragePort) and ports.vercelBlob (an escape hatch, see below). Configuration comes from BLOB_* env vars:

| Env var | Meaning | | --- | --- | | BLOB_READ_WRITE_TOKEN | Read-write token. Set automatically on Vercel deployments with a connected Blob store; set it manually elsewhere. | | BLOB_ACCESS | Store-wide access level: private (default) or public. | | BLOB_KEY_PREFIX | Optional prefix applied to every object key. | | BLOB_STORE_ID | Optional store id when authenticating with a Vercel OIDC token. |

Local storage keeps working with zero setup by switching on the token, the same way the environment-swapped rate-limit providers work:

import { createLocalStorageProvider } from "@beignet/provider-storage-local";
import { createVercelBlobStorageProvider } from "@beignet/provider-storage-vercel-blob";

export const providers = [
  // Vercel Blob in deployed environments (local disk does not survive
  // serverless); the local provider keeps dev working with zero setup.
  process.env.BLOB_READ_WRITE_TOKEN
    ? createVercelBlobStorageProvider()
    : createLocalStorageProvider(),
] as const;

Visibility

Vercel Blob stores per-object access at write time but does not report it back from head(...), so this adapter keeps the whole store uniform: every object shares the configured access level, and a put(...) that requests a different visibility is rejected with an error instead of silently misreporting visibility on later reads. Run two providers over two Blob stores when an app needs both levels.

publicUrl(...) returns the blob URL for public stores and null for private stores. Private objects should be served through app routes that enforce the app's own authorization, then stream the body from ctx.ports.storage.get(...).

Vercel Blob has no arbitrary per-object metadata, so StorageObject.metadata is always reported empty. Cache lifetimes map from the Cache-Control max-age directive to Vercel Blob's cacheControlMaxAge seconds; other directives do not survive the mapping.

Direct port factory

Use the direct factory when you own provider wiring or need a second store:

import { createVercelBlobStorage } from "@beignet/provider-storage-vercel-blob";

const storage = createVercelBlobStorage({
  access: "public",
  keyPrefix: "avatars",
  token: process.env.AVATARS_BLOB_TOKEN,
});

Omit token to let @vercel/blob read BLOB_READ_WRITE_TOKEN from the environment. The client option accepts a fake SDK surface for tests.

Request cost

Some StoragePort promises need an extra Blob API round-trip:

  • put(...) issues a post-write head(...) because the port returns the authoritative stored object, not an echo of inputs.
  • delete(...) issues a pre-delete head(...) because Vercel Blob's del(...) does not report whether the object existed.

Escape hatch

ports.vercelBlob exposes the raw pieces for integrations the port does not cover:

const { client, access, keyPrefix, objectKey, checkHealth } = ctx.ports.vercelBlob;

await client.list({ prefix: objectKey("exports"), limit: 100 });
const health = await checkHealth();

checkHealth() issues a one-item list(...) and reports { ok, message?, metadata } for readiness endpoints.

Devtools

When @beignet/devtools is installed before this provider, storage operations appear under the dashboard's Storage watcher. The provider records storage.put, storage.get, storage.stat, storage.delete, storage.exists, and storage.publicUrl events with key, size, and duration; failures are recorded with .failed event names and the original error is rethrown.

Failure behavior

Missing objects resolve to null (get, stat, publicUrl) or false (delete, exists) — BlobNotFoundError never escapes the port. All other SDK errors are rethrown unchanged after an instrumentation event, including missing-token errors, so misconfiguration fails loudly rather than pretending storage is empty.

Direct uploads

This package covers server-mediated storage through StoragePort. Vercel Blob's browser-direct uploads use its own client-token protocol (@vercel/blob/client), which does not fit Beignet's plain presigned-PUT UploadSignerPort; use createS3UploadSigner from @beignet/provider-storage-s3 when direct uploads are a requirement, or Vercel's client SDK directly.

Local and tests

Keep dev and tests on @beignet/provider-storage-local or createMemoryStorage() from @beignet/core/ports; both implement the same port. Inject a fake VercelBlobClient through the client/createClient options to test app code against this adapter without network access.

Deployment notes

Connect a Blob store to the Vercel project so BLOB_READ_WRITE_TOKEN is provisioned automatically, and prefer private stores unless objects are genuinely world-readable: public blob URLs are unauthenticated and long-cached.