Filesystem
Local filesystem - the dev/test adapter. Uses node:fs/promises with a sidecar .meta.json per file. Not for production.
Installation
This adapter has no extra peer dependencies - the runtime (Node or Bun) provides everything it needs.
npm install files-sdkUsage
Local filesystem. The dev/test adapter - point it at a directory and it implements the same Adapter contract as the cloud adapters using node:fs/promises. Each upload writes the body and a sidecar .meta.json file alongside it (Content-Type, ETag, user metadata) so reads round-trip cleanly. Not for production: there's no replication, no signing, no auth.
import { Files } from "files-sdk";
import { fs } from "files-sdk/fs";
// Writes objects under `./.uploads` with a sidecar `.meta.json`
// per file for Content-Type, ETag, and user metadata. Designed for
// dev and CI - same Adapter contract as the cloud adapters, so swap
// it in via env without changing call sites.
const files = new Files({
adapter: fs({
root: "./.uploads",
// Optional: configure if a dev server exposes the same root over
// HTTP, so url() returns a browser-friendly URL instead of file://.
// urlBaseUrl: "http://localhost:3000/files",
}),
});Options
Prop
Type
Storage layout
Body at `${root}/${key}`; sidecar at `${root}/${key}.meta.json`. Sidecars survive cp -r / git mv / partial-tree deletion. list() hides them. ETag is a SHA-1-derived stable hash computed at upload time. Files written into root by hand without a sidecar are still readable - contentType falls back to application/octet-stream and etag is absent.
Compatibility
| Method | Status | Notes |
|---|---|---|
upload | ✅ | |
download | ✅ | |
delete | ✅ | |
list | ✅ | |
search | ✅ | |
head | ✅ | |
exists | ✅ | |
copy | ✅ | |
url | ⚠️ | Returns a file:// URL by default - fine for CLIs and tests, not browsers. With urlBaseUrl set, returns <urlBaseUrl>/<key> so a dev server (Next.js /public mount, serve-static, etc.) can deliver the body. responseContentDisposition throws because neither file:// nor static-server URLs have a signature mechanism in which to bind the override. |
signedUploadUrl | ⚠️ | Throws without urlBaseUrl - the fs adapter has no built-in upload server, so there's nothing to sign against. With urlBaseUrl set, returns a PUT URL with ?expires=, ?content-type=, and ?max-size= query params for a dev upload-handler to validate. The fs adapter does not enforce the params itself. |