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

`files.list(options?)`

Cursor-paginated listing with prefix filter. Each item is a [`FileInfo`](/docs/api/stored-file): metadata only, with no body. Call [`download`](/docs/api/download) for an item's bytes.

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

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

`limit` is the page size, capped per provider (most top out around 1,000, the default). It must be a positive integer: `0`, a negative or fractional number, or `NaN` throws an `Invalid` [`FilesError`](/docs/api/errors) before any provider call.

## 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 [`FileInfo`](/docs/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](/docs/retries), and fires one [`onAction`](/docs/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`. One `list` caveat carries over to the walk: the folder-based [Box](/docs/adapters/box), [OneDrive](/docs/adapters/onedrive), and [SharePoint](/docs/adapters/sharepoint) adapters list **one folder at a time** and don't recurse. `list` reads the folder that `prefix` points into (everything up to its last `/`, or the root folder when there's no prefix), so `listAll` walks every page of that folder but never descends into its subfolders. Walk each subfolder with its own `prefix`, discovering them with [`delimiter: "/"`](#listing-folders-with-delimiter).

## 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](/docs/adapters/s3) and the whole `s3()` family, [R2](/docs/adapters/r2), [Bun's S3](/docs/adapters/bun-s3), [Google Cloud Storage](/docs/adapters/gcs), [Firebase Storage](/docs/adapters/firebase-storage), [Azure Blob](/docs/adapters/azure), plus the local [`fs`](/docs/adapters/fs), [in-memory](/docs/adapters/memory), [FTP](/docs/adapters/ftp), [SFTP](/docs/adapters/sftp), [WebDAV](/docs/adapters/webdav), [Google Drive](/docs/adapters/google-drive), and [Cloudinary](/docs/adapters/cloudinary) adapters (which synthesize prefixes from the key list).
- **`"/"` only** — the folder-based providers: [Vercel Blob](/docs/adapters/vercel-blob), [Netlify Blobs](/docs/adapters/netlify-blobs), [Supabase](/docs/adapters/supabase), [Dropbox](/docs/adapters/dropbox), [Box](/docs/adapters/box), [OneDrive](/docs/adapters/onedrive), [SharePoint](/docs/adapters/sharepoint). Any other delimiter throws.
- **Unsupported** — adapters that can't return common prefixes: [UploadThing](/docs/adapters/uploadthing), [Appwrite](/docs/adapters/appwrite), [PocketBase](/docs/adapters/pocketbase), [Convex](/docs/adapters/convex), and [Bunny Storage](/docs/adapters/bunny-storage). Passing a `delimiter` throws a [`FilesError`](/docs/api/errors) before any provider call rather than silently returning a flat list — branch on `files.capabilities.delimiter` (`"any"`, `"slash"`, or `false`) 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" />
