Skip to content
Files SDK
Esc
↑↓navigate↵open⌘Jpreview
On this page

Appwrite

Appwrite Storage via the official node-appwrite SDK. Auto-loads APPWRITE_ENDPOINT, APPWRITE_PROJECT_ID, and APPWRITE_API_KEY, or pass an existing client.

Installation

node-appwrite is an optional peer dependency of files-sdk - install alongside the SDK so the adapter’s imports resolve at runtime.

npm install files-sdk node-appwrite
pnpm add files-sdk node-appwrite
yarn add files-sdk node-appwrite
bun add files-sdk node-appwrite
nub add files-sdk node-appwrite
aube add files-sdk node-appwrite

Usage

import { Files } from "files-sdk";
import { appwrite } from "files-sdk/appwrite";

const files = new Files({
  adapter: appwrite({
    bucket: "uploads",
    // Auto-loads from APPWRITE_ENDPOINT, APPWRITE_PROJECT_ID,
    // and APPWRITE_API_KEY. Or pass an existing node-appwrite
    // Client or Storage instance via `client`.
    //
    // Note: Appwrite keys (IDs) must start with a letter or digit,
    // use only [a-zA-Z0-9._-], and be at most 36 chars.
    // Slashes (/) are not supported.
  }),
});

Options

PropType
bucketstring

Appwrite storage bucket ID.

Typestring
client?Client | Storage

Existing client instance or Storage instance. Highest precedence.

TypeClient | Storage
endpoint?string

Appwrite API endpoint (e.g. `https://cloud.appwrite.io/v1`). Falls back to `APPWRITE_ENDPOINT` then `NEXT_PUBLIC_APPWRITE_ENDPOINT`.

Typestring
projectId?string

Appwrite Project ID. Falls back to `APPWRITE_PROJECT_ID` then `NEXT_PUBLIC_APPWRITE_PROJECT_ID`.

Typestring
key?string

Appwrite API Key. Falls back to `APPWRITE_API_KEY` then `APPWRITE_KEY`.

Typestring
public?boolean

Set to `true` if the bucket is configured as a public bucket. `url()` will then return a constructed permanent, unsigned URL (the `/view` endpoint, or `/download` for `responseContentDisposition: "attachment"`; any other disposition throws). Otherwise, `url()` throws an error.

Typeboolean

Limitations

File IDs (keys) must start with an alphanumeric and use only [a-zA-Z0-9._-], max 36 characters (no slashes) - every method that takes a key rejects an invalid one before the API call. list({ prefix }) queries startsWith("$id", ...) against the canonical file ID, so files created outside the adapter where the display name differs from $id won’t be matched by prefix. Resumable uploads (control) send chunks over Appwrite’s REST API with the API key, so they need key (or APPWRITE_API_KEY); an adapter built from a pre-built client throws on them.

Compatibility

Method Status Notes
upload ⚠️ Stream bodies are buffered up-front - InputFile.fromBuffer has no streaming form, so streamed uploads can’t avoid materializing the body in memory. User metadata and cacheControl throw - Appwrite’s createFile has no equivalent fields. contentType is silently ignored - Appwrite auto-detects mime from the payload and has no override. Uploading onto an existing key replaces the file by deleting it and creating it again (Appwrite can’t update a file’s content): not atomic, and file-level permissions on the old file aren’t carried over. Resumable uploads (control) don’t replace: Appwrite rejects a chunked upload onto an existing file ID, so delete the key first.
download ✅
delete ✅
list ✅
search ✅
head ✅
exists ✅
copy ⚠️ Read-then-write - Appwrite has no server-side copy primitive, so the source is downloaded and re-uploaded. Costs an egress + an ingest; not atomic. An existing destination is replaced the same way upload replaces one.
url ⚠️ Throws by default because Appwrite SDKs cannot mint presigned reading URLs with keys. Set public: true at construction to return the constructed, permanent Appwrite /view URL. expiresIn is ignored. responseContentDisposition: "attachment" returns the /download URL (served as an attachment named after the stored file name); any other disposition, such as a custom filename or inline, throws - Appwrite has no per-request override.
signedUploadUrl ❌ No presigned upload primitive in Appwrite. Use JWTs or client SDKs for direct uploads.

Was this page helpful?