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

@86d-app/storage

v0.0.30

Published

<p align="center"> <a href="https://86d.app"> <img src="https://86d.app/logo" height="96" alt="86d" /> </a> </p>

Readme

[!WARNING] This project is under active development and is not ready for production use. Please proceed with caution. Use at your own risk.

Storage

Pluggable file storage abstraction for the 86d platform. Ships with three providers: local filesystem, S3-compatible (AWS, MinIO, etc.), and Vercel Blob.

Installation

npm install @86d-app/storage

For Vercel Blob support, also install the optional peer dependency:

npm install @vercel/blob

Usage

From Environment Variables (recommended)

import { createStorageFromEnv } from "@86d-app/storage";

const storage = createStorageFromEnv();

// Upload a file
const result = await storage.upload({
  key: "images/product-photo.png",
  content: Buffer.from(fileData),
  contentType: "image/png",
});

console.log(result.url); // public URL
console.log(result.key); // "images/product-photo.png"

// Delete a file
await storage.delete({ key: "images/product-photo.png" });

// Get a public URL
const url = storage.getUrl("images/product-photo.png");

// Check if the storage backend is available
const healthy = await storage.healthCheck();

Local Storage

import { createStorage } from "@86d-app/storage";

const storage = createStorage({
  provider: "local",
  localDir: "./uploads",
  localBaseUrl: "/uploads",
});

Files are written to disk under localDir. The localBaseUrl is used to construct public URLs (e.g. /uploads/images/photo.png). Your application must serve this directory statically.

S3-Compatible Storage

import { createStorage } from "@86d-app/storage";

const storage = createStorage({
  provider: "s3",
  s3Endpoint: "https://s3.amazonaws.com",
  s3Bucket: "my-store-uploads",
  s3Region: "us-east-1",
  s3AccessKey: "AKIA...",
  s3SecretKey: "wJal...",
});

Works with AWS S3, MinIO, and any S3-compatible service. Uses path-style URLs for broad compatibility. Signs requests with AWS Signature V4 and has zero external dependencies.

Vercel Blob

import { createStorage } from "@86d-app/storage";

const storage = createStorage({
  provider: "vercel",
});

Requires @vercel/blob as a peer dependency and the BLOB_READ_WRITE_TOKEN environment variable. Optionally set VERCEL_BLOB_STORAGE_HOSTNAME for URL construction via getUrl().

Configuration

Environment Variables

| Variable | Description | Default | |---|---|---| | STORAGE_PROVIDER | Provider to use: local, s3, or vercel | local | | STORAGE_LOCAL_DIR | Directory for local file storage | ./uploads | | STORAGE_LOCAL_BASE_URL | Base URL for serving local files | /uploads | | S3_ENDPOINT | S3-compatible endpoint URL | -- | | S3_BUCKET | S3 bucket name | -- | | S3_REGION | S3 region | us-east-1 | | S3_ACCESS_KEY | S3 access key ID | -- | | S3_SECRET_KEY | S3 secret access key | -- | | BLOB_READ_WRITE_TOKEN | Vercel Blob auth token (Vercel provider) | -- | | VERCEL_BLOB_STORAGE_HOSTNAME | Vercel Blob hostname for URL construction | -- |

API Reference

StorageProvider Interface

All providers implement this interface:

interface StorageProvider {
  /** Upload a file to storage. */
  upload(options: StorageUploadOptions): Promise<StorageUploadResult>;

  /** Delete a file from storage. */
  delete(options: StorageDeleteOptions): Promise<void>;

  /** Get a public URL for a stored file. */
  getUrl(key: string): string;

  /** Check if the storage backend is available. */
  healthCheck(): Promise<boolean>;
}

StorageUploadOptions

interface StorageUploadOptions {
  key: string;                      // Path/key to store the file under
  content: Buffer | ArrayBuffer;    // File content
  contentType: string;              // MIME type (e.g. "image/png")
  public?: boolean;                 // Whether publicly readable (default: true)
}

StorageUploadResult

interface StorageUploadResult {
  url: string;   // Public URL of the uploaded file
  key: string;   // Storage key/path
}

Factory Functions

| Function | Description | |---|---| | createStorage(config) | Create a provider from a StorageConfig object | | createStorageFromEnv() | Create a provider from environment variables |

Provider Classes

| Class | Description | |---|---| | LocalStorageProvider | Filesystem storage using Node fs | | S3StorageProvider | S3-compatible storage with AWS Signature V4 | | VercelBlobProvider | Vercel Blob storage via @vercel/blob |

Provider-Specific Notes

Local

  • Creates the base directory automatically on initialization.
  • Creates nested subdirectories on upload as needed.
  • Deleting a non-existent file is a silent no-op.
  • Health check verifies the base directory exists on disk.

S3

  • Uses path-style URLs (endpoint/bucket/key) for MinIO and other S3-compatible services.
  • Implements AWS Signature V4 signing internally -- no AWS SDK required.
  • All four config fields (s3Endpoint, s3Bucket, s3AccessKey, s3SecretKey) are required; the factory throws if any are missing.
  • Delete ignores 404 responses (already deleted).
  • Health check sends a HEAD request to the bucket; treats 200, 403, and 404 as healthy.

Vercel Blob

  • @vercel/blob is an optional peer dependency -- dynamically imported at call time.
  • Requires BLOB_READ_WRITE_TOKEN environment variable for authentication.
  • getUrl() uses VERCEL_BLOB_STORAGE_HOSTNAME if set; otherwise returns the raw key as a fallback (prefer using the URL returned from upload()).
  • Health check returns true if BLOB_READ_WRITE_TOKEN is present.