Backends
IndexedDB and filesystem backends, Tauri integration, and the Chroma Desktop postMessage bridge.
Chroma-Fs implements two storage backends behind one API. The factory (createChromaFs) selects the backend from config and runtime environment.
IndexedDB
Used for static apps and any browser context without Tauri.
- Virtual directory tree stored in a single IndexedDB object store
- Paths normalized to forward slashes (
notes/hello.txt) - Parent directories created implicitly on
writeFile deleteon a directory removes all descendants
No native files are created — data stays in the browser profile until cleared.
Filesystem (Tauri / Desktop)
Used when backend: "filesystem" and a filesystem adapter is available.
Direct Tauri (rare)
If the app runs with window.__TAURI__ and is not in an iframe, Chroma-Fs uses @tauri-apps/plugin-fs via createDefaultTauriFsAdapter, scoped to AppLocalData + basePath.
Chroma Desktop iframe bridge (default for packaged apps)
Chroma Desktop hosts apps in an <iframe> at http://127.0.0.1:<port>/<app-id>/index.html. Iframes cannot call Tauri directly.
Flow:
- App imports
@chroma/fs→ detects iframe + desktop →createPostMessageAdapter() - Adapter sends
{ channel: "chroma-fs", id, op, args }towindow.parent - Chroma Desktop parent handles the message and calls scoped Rust commands
- Parent responds with
{ channel: "chroma-fs", id, ok, result | error }
Scoped data directories
Rust commands in Chroma Desktop resolve paths under:
<tauri-app-data>/apps/<app-id>/data/<relative-path>- Imported apps:
app-idis the import folder name - Develop mode (
chroma devon dynamic):app-idisdevelop
Path traversal (..) is rejected.
Tauri commands (Chroma Desktop)
| Command | Purpose |
|---|---|
fs_read_file | Read bytes |
fs_read_text | Read UTF-8 string |
fs_write_file | Write bytes |
fs_write_text | Write string |
fs_remove | Delete file/dir |
fs_exists | Check existence |
fs_read_dir | List directory |
fs_mkdir | Create directory |
fs_stat | File metadata |
tauri-plugin-fs is registered with scoped capabilities (fs:scope-appdata-recursive) for the shell; app iframe traffic goes through the postMessage bridge and Rust commands for tighter per-app isolation.
Backend selection diagram
Testing adapters
Use createMockTauriFsAdapter patterns or pass a custom adapter in createChromaFs({ adapter }) for unit tests without IndexedDB or Tauri.