@raypx/storage
Object storage abstraction backed by unstorage.
@raypx/storage provides a unified object storage API backed by unstorage. It supports local filesystem and Redis drivers, with a pluggable interface for adding S3/R2 in the future.
Core API
import { createStorage } from "@raypx/storage"
const storage = createStorage()
// Store an object
await storage.putObject({ key: "avatars/user.png", body: buffer })
// Retrieve an object
const { key, body } = await storage.getObject("avatars/user.png")
// Generate a signed upload URL (local driver only)
const { url, method, headers } = await storage.createSignedUploadUrl({
key: "uploads/document.pdf",
contentType: "application/pdf",
})Factory
createStorage(options?) creates a Storage instance. The driver is selected via the STORAGE_DRIVER environment variable or the options.driver parameter:
const storage = createStorage({
driver: "local",
local: { rootDir: ".uploads" },
})Drivers
Local (Filesystem)
Uses fs-lite driver from unstorage. Files are stored on the local filesystem.
| Option | Environment Variable | Default | Description |
|---|---|---|---|
driver | STORAGE_DRIVER | "local" | Must be "local" |
local.rootDir | STORAGE_LOCAL_ROOT | .storage | Root directory for stored files |
The local driver supports createSignedUploadUrl(), which returns a URL pointing to the app's /api/files/upload endpoint with the key as a query parameter.
Redis
Uses the Redis driver from unstorage. Connection is lazily initialized on first use.
| Option | Environment Variable | Default | Description |
|---|---|---|---|
driver | STORAGE_DRIVER | -- | Must be "redis" |
redis.url | STORAGE_REDIS_URL | (required) | Redis connection URL |
redis.base | STORAGE_REDIS_BASE | -- | Key prefix namespace |
redis.ttl | STORAGE_REDIS_TTL_SECONDS | -- | Default TTL in seconds |
const storage = createStorage({
driver: "redis",
redis: { url: "redis://localhost:6379", base: "raypx:", ttl: 3600 },
})The STORAGE_REDIS_URL environment variable is required when using the Redis driver. If missing, createStorage() throws an error.
Storage Interface
interface Storage {
putObject(input: { key: string; body: Uint8Array | Buffer | string; contentType?: string }): Promise<{ key: string }>
getObject(key: string): Promise<{ key: string; body: Buffer }>
createSignedUploadUrl?(input: { key: string; contentType?: string }): Promise<{ key: string; method: "PUT"; url: string; headers: Record<string, string> }>
}Note that createSignedUploadUrl is optional and only implemented by the local driver. The Redis driver does not provide signed URLs.
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
STORAGE_DRIVER | No | "local" | Storage driver: "local" or "redis" |
STORAGE_LOCAL_ROOT | No | .storage | Root directory for local filesystem storage |
STORAGE_REDIS_URL | No | -- | Redis URL (required when driver is "redis") |
STORAGE_REDIS_BASE | No | -- | Redis key prefix |
STORAGE_REDIS_TTL_SECONDS | No | -- | Default TTL for Redis entries |
Future: S3/R2 Driver
An S3/R2 driver is planned for future releases. It will implement createSignedUploadUrl() using presigned URLs, enabling direct-to-cloud uploads from the browser.