Skip to main content
Mirage ships DropboxResource in two runtimes:
  • @struktoai/mirage-node, uses client_id + client_secret + long-lived refresh token to fetch short-lived access tokens server-side.
  • @struktoai/mirage-browser, supports the same refresh token via PKCE (no client secret in the bundle).
Both runtimes hit the same Dropbox v2 HTTP API: /2/files/list_folder for directories, /2/files/download for content, and /2/files/upload / create_folder_v2 / delete_v2 / move_v2 / copy_v2 for writes (single-call uploads cap at ~150 MB). Credentials are obtained the same way in both runtimes, see Dropbox Credentials. The Python package ships the same backend, see Dropbox (Python).

Node (server-side)

The DropboxTokenManager caches the access token in memory and refreshes it ~5 minutes before expiry, so cold-start API calls don’t pay the refresh round-trip.

Mount a subfolder

Pass rootPath to expose a single Dropbox folder as the mount root instead of the whole account. Every command and FUSE/VFS op is scoped to that folder; paths outside it are unreachable.
rootPath accepts Team/data, /Team/data, or /Team/data/ (all normalized the same way); .. segments are rejected. Config dictionaries (e.g. via the resource registry) may spell it root_path. Omitting it (or passing /) mounts the account root as before.

Search push-down

By default a recursive grep/rg walks the tree and downloads every file. With contentSearch: true (config dictionaries may spell it content_search), both commands first ask /2/files/search_v2 which files contain the pattern’s literal, then download and scan only those candidates — the output stays exactly GNU/ripgrep because the local scan still decides every match. Regex patterns narrow on an extracted required literal; flags whose output must see every file in scope (grep -v, grep -c, rg -v, rg --type/--glob) always take the full walk, as do file operands and multi-pattern (-e/-f) runs. An empty or failed search also falls back to the full walk.
The knob is off by default for two reasons: full-text content search is plan-gated (Dropbox Professional/Essentials/Business and up — on other plans search_v2 silently matches file names only, so a narrowed scan would miss content matches), and Dropbox’s search index lags recent writes by a short delay, so a push-down may miss files written moments earlier. Only enable it when the account’s plan includes full-text search and slightly stale results are acceptable. See Dropbox (Python) — Search push-down for the mirrored Python knob.

Browser (PKCE, no client secret)

Set the redirect URI on your Dropbox app’s Settings tab to your dev/prod origin (e.g. http://localhost:5173/dropbox_pkce.html). The bundled examples/typescript/browser/src/dropbox_pkce.ts runs the full PKCE dance end-to-end and persists the refresh token to localStorage.

VFS mode (patchNodeFs)

Mirage exposes a patchNodeFs(workspace) shim that routes fs.promises.* calls under a mount through the workspace, so any library that uses Node’s fs API can read directly from Dropbox without code changes.
Only fs.promises.* (the async API) is patched. Sync forms like fs.statSync and fs.readFileSync aren’t supported because remote reads can’t block the event loop.

FUSE mode

For tools that need a real filesystem path (CLI tools, editors, system utilities), mount the workspace under FUSE:
Requires macFUSE on macOS or libfuse on Linux. See FUSE setup.

Available commands

DropboxResource ships the same shell command set as the GDrive resource:
  • Filesystem: ls, cat, head, tail, nl, wc, stat, find, tree, du, file, realpath, basename, dirname
  • Write (on a WRITE mount): tee, touch, mkdir, rm, rmdir, mv, cp, truncate, shell redirection (> / >>)
  • Search/text: grep, rg, awk, sed, sort, uniq, cut, diff, cmp, jq
  • Encoding: base64
  • Format-aware: cat_parquet, cat_feather, cat_hdf5, head_parquet, head_feather, head_hdf5, cut_*, grep_*, ls_*, stat_*, tail_*, wc_*, file_* for .parquet, .feather, .hdf5/.h5, .orc files
The format-aware commands transparently decode binary tabular files, so cat /dropbox/data/example.parquet returns a column preview instead of binary garbage.

Examples

End-to-end runnable scripts are in examples/typescript/dropbox/: