A unified storage SDK for object and blob backends. One small, honest API. Web-standards I/O. An escape hatch when you need the native client.
npm install files-sdkEach provider's native SDK is an optional peer dependency — install only the ones you actually use, alongside files-sdk itself. A few examples:
# S3 (and any S3-compatible: R2, MinIO, DigitalOcean Spaces, Backblaze B2, Wasabi, …)
npm install files-sdk @aws-sdk/client-s3 @aws-sdk/s3-presigned-post @aws-sdk/s3-request-presigner
# Google Cloud Storage
npm install files-sdk @google-cloud/storage google-auth-library
# Azure Blob Storage
npm install files-sdk @azure/storage-blob @azure/core-auth @azure/identity
# Vercel Blob
npm install files-sdk @vercel/blobSee files-sdk.dev for the per-adapter install command. If you import an adapter without its peer installed, Node will throw ERR_MODULE_NOT_FOUND naming the missing package.
import { Files } from "files-sdk";
import { s3 } from "files-sdk/s3";
const files = new Files({
adapter: s3({ bucket: "uploads" }),
});
await files.upload("avatars/abc.png", file, { contentType: "image/png" });
const got = await files.download("avatars/abc.png");
const exists = await files.exists("avatars/abc.png");Swap the adapter import (files-sdk/r2, files-sdk/gcs, files-sdk/azure, …) and the rest of your code stays the same.
Use files.file(key) when your application code works with the same object repeatedly:
const avatar = files.file("avatars/abc.png");
await avatar.upload(file, { contentType: "image/png" });
if (await avatar.exists()) {
const meta = await avatar.head();
const url = await avatar.url({ expiresIn: 300 });
}
await avatar.delete();File handles are a thin layer over the same adapter methods, so adapters do not need to implement anything extra.
- One API across providers —
upload,download,head,exists,delete,copy,move,list/listAll,url,signedUploadUrl, plusfile(key)for a key-scoped handle. The shape is the same on S3, GCS, Azure, Vercel Blob, the local filesystem, and consumer providers like Dropbox.existsreturnsfalseonly when the provider reportsNotFound; auth, permission, and transport failures still throw. - Web-standard I/O — bodies are
Blob,File,ReadableStream,Uint8Array,ArrayBuffer, orstring. No provider-specific types leak into your code. - Escape hatch — every adapter exposes its native client at
files.raw, so provider-specific features are one property access away. - Tree-shakeable — each adapter is a separate entry point. You only bundle what you import.
A growing catalog covering S3 and S3-compatible stores, the major cloud blob platforms, edge/serverless blob services, the local filesystem, and consumer file providers. See files-sdk.dev for the current list and per-adapter setup.
A growing set of subpaths wrap a configured Files instance as ready-made tools for popular AI SDKs — currently the Vercel AI SDK (files-sdk/ai-sdk), OpenAI's Responses API and Agents SDK (files-sdk/openai), and Anthropic's Claude Agent SDK (files-sdk/claude). All share the same file operations and approval-gating defaults, so models can browse, read, and (optionally) mutate your bucket through the same unified surface as your application code. See files-sdk.dev for the current list and per-SDK setup.
MIT