---
title: list
description: Cursor-paginated listing with a prefix filter; each item is a StoredFile with a lazy body accessor. listAll walks every page; a delimiter returns folders.
---

`files.list(options?)`

Cursor-paginated listing with prefix filter. Each item is a [`StoredFile`](/api/stored-file) with a lazy body accessor.

```ts lineNumbers
const { items, cursor } = await files.list({
  prefix: "avatars/",
  limit: 100,
});

if (cursor) {
  const next = await files.list({ prefix: "avatars/", cursor });
}
```

## Walking every page with `listAll`

`list` returns one page plus a `cursor`; most callers actually want "walk everything under this prefix", which is a manual cursor loop. `files.listAll(options?)` is that loop as an async iterable:

```ts lineNumbers
for await (const file of files.listAll({ prefix: "avatars/" })) {
  console.log(file.key, file.size);
}
```

Each item is the same [`StoredFile`](/api/stored-file) `list` yields. `prefix` scopes the walk; `limit` sets the **page size** each underlying `list` fetches (not a total cap), and a `cursor` resumes from a prior position. Every page is a real `list` call, so it honors the client `prefix`, [retries and timeouts](/retries), and fires one [`onAction`](/api/onaction) `list` event per page. `break` out of the loop to stop early — no further pages are fetched.

`listAll` runs on every adapter, since it's built on `list`. Two `list` caveats carry over to the walk:

- **[Netlify Blobs](/adapters/netlify-blobs) exposes no pagination cursor.** Call `listAll()` with **no `limit`** and it returns everything in a single page (correct); pass a `limit` and there is no next page to follow, so the walk stops at that many. On Netlify, omit `limit` when you mean "walk everything."
- **Non-recursive adapters** ([Box](/adapters/box), [OneDrive](/adapters/onedrive), [SharePoint](/adapters/sharepoint)) list only the immediate children of the root folder. `listAll` walks every page, but it can't descend into subfolders the underlying `list` never returns.

## Listing folders with `delimiter`

Pass a `delimiter` to collapse keys at that boundary into **common prefixes** ("folders") — the building block for a file-browser UI. With `delimiter: "/"`, a page returns only the files directly under `prefix` in `items`, and the subfolders in `prefixes` (full keys including the trailing delimiter); keys nested deeper are folded into those prefixes rather than listed.

```ts lineNumbers
const { items, prefixes } = await files.list({
  prefix: "photos/",
  delimiter: "/",
});

// Render one level of a browser:
for (const folder of prefixes ?? []) {
  console.log("📁", folder); // "photos/2023/", "photos/2024/"
}
for (const file of items) {
  console.log("📄", file.key); // "photos/cover.jpg"
}
```

`prefixes` is omitted when no `delimiter` is set or none are found. The page `cursor` walks `items` and `prefixes` together (a folder counts as one entry against `limit`); hold `prefix` **and** `delimiter` constant across a paginated sequence, just like `prefix` alone.

[`listAll`](#walking-every-page-with-listall) ignores `delimiter` — it walks the whole tree, so use `list` directly for the folder view.

### Provider support

- **Any delimiter string** — the object stores with native common-prefix listing: [S3](/adapters/s3) and the whole `s3()` family, [R2](/adapters/r2), [Google Cloud Storage](/adapters/gcs), [Firebase Storage](/adapters/firebase-storage), [Azure Blob](/adapters/azure), plus the local [`fs`](/adapters/fs), in-memory, [FTP](/adapters/ftp), [SFTP](/adapters/sftp), [Google Drive](/adapters/google-drive), and [Cloudinary](/adapters/cloudinary) adapters (which synthesize prefixes from the key list).
- **`"/"` only** — the folder-based providers: [Vercel Blob](/adapters/vercel-blob), [Netlify Blobs](/adapters/netlify-blobs), [Supabase](/adapters/supabase), [Dropbox](/adapters/dropbox), [Box](/adapters/box), [OneDrive](/adapters/onedrive), [SharePoint](/adapters/sharepoint). Any other delimiter throws.
- **Unsupported** — providers with no folder/prefix concept: [UploadThing](/adapters/uploadthing), [Appwrite](/adapters/appwrite), [PocketBase](/adapters/pocketbase), [Convex](/adapters/convex), and [Bun's S3](/adapters/bun-s3) (whose list response carries no common prefixes). Passing a `delimiter` throws a [`FilesError`](/api/errors) before any provider call rather than silently returning a flat list — branch on `adapter.supportsDelimiter` to check at runtime.

## Options

Both `list` and `listAll` take the same options:

<AutoTypeTable
  path="../../packages/files-sdk/src/index.ts"
  name="ListOptions"
/>

## Result

<AutoTypeTable path="../../packages/files-sdk/src/index.ts" name="ListResult" />
