File buckets
Upload, download and isolate files per user, declared in your schema like any other resource.
File Buckets are experimental. The API may change in future releases. Currently only the memory backend is supported, so files are not persisted across server restarts.
Buckets provide a type-safe file storage abstraction for uploading, downloading, and managing files in your Sp00ky application. They integrate directly with your SurrealDB schema for permission control and with the Sp00ky CLI for guided setup.
Defining a Bucket
Buckets are defined in SurrealQL using the DEFINE BUCKET statement. Create a .surql file in your src/buckets/ directory:
Permission Variables
$action: The operation type:'put','get', or'delete'file::head($file).size: The file size in bytesfile::key($file): The file path/key
This example allows unrestricted reads and deletes, but restricts uploads to images under 5MB.
Configuration
Reference your bucket files in sp00ky.yml:
After adding or modifying a bucket, regenerate your types by running spky so the bucket names and config are available in your generated schema.
CLI: Adding a Bucket
The fastest way to add a bucket is with the CLI:
This walks you through an interactive setup with presets for common use cases:
| Preset | Extensions | Max Size | Path Isolation |
|---|---|---|---|
| Avatars | jpg, jpeg, png, gif, webp | 2 MB | Yes |
| Images | jpg, jpeg, png, gif, webp, svg | 10 MB | No |
| Documents | pdf, doc, docx, txt, csv, xlsx | 25 MB | No |
| Video | mp4, webm, mov, avi | 100 MB | No |
| Audio | mp3, wav, ogg, flac, aac | 50 MB | No |
| Custom | You choose | You choose | You choose |
The CLI generates the .surql file and updates your sp00ky.yml automatically.
Generated Schema
After running spky, your generated schema includes bucket metadata for type-safe access:
Bucket names are extracted as a union type, so db.bucket('...') only accepts valid bucket names from your schema.
Core API
Access a bucket from your Sp00kyClient or SyncedDb instance:
SolidJS Hooks
useFileUpload
Upload files with built-in validation against your bucket configuration (max size, allowed extensions):
The hook validates file size and extension before attempting the upload, providing instant feedback.
API
useDownloadFile
Reactively download and cache files as blob URLs:
Features:
- Caching: Downloaded files are cached with reference counting. Disable with
{ cache: false }. - Deduplication: Concurrent downloads for the same path are deduplicated.
- Auto-cleanup: Blob URLs are revoked when the component unmounts or the path changes.
- Reactivity: Automatically re-fetches when the path accessor changes.
API
Per-User Path Isolation
When enabled (via the pathPrefixAuth option in the CLI), file paths are automatically prefixed with the authenticated user’s ID. This ensures users can only access their own files.
Per-user path isolation is enforced at the database level. The path prefix is applied transparently. Your application code uses simple paths.
Local Caching
Bucket reads go through a durable client-side cache. Bytes land in OPFS under sp00ky-blobs/<bucketId>/<bucket>/<path>, so a file downloaded once survives a reload, paints instantly on the next visit, and is available offline. The cache is namespaced per signed-in user and is on by default wherever OPFS is writable; elsewhere it degrades to per-tab memory.
Nothing expires on a timer. A file is dropped only when the app invalidates its path (put() and delete() do this for you), when boot reconcile finds no file behind a manifest row, or when the cache exceeds its byte budget — in which case the least-recently-used unpinned entries that nothing is currently rendering go first.
Live counters — cached bytes, budget, hits/misses, evictions — are in the DevTools Storage tab under “Bucket file cache”.
Current Limitations
- Memory backend only: Files are stored in memory and not persisted across restarts. Additional storage backends (S3, filesystem, etc.) are planned.
- No streaming: Files are uploaded and downloaded as complete blobs. No chunked upload or progress tracking yet.
- No transactions: Bucket operations do not participate in database transactions.