File storage

Uploads, presigned out of the box.

Get presigned upload URLs without standing up an upload service. Files land on local disk in development and any S3-compatible bucket — R2, Backblaze, MinIO, AWS — in production, switched by one environment variable.

components/Avatar.tsx
import { FileUpload } from "@pylonsync/react";

function AvatarPicker() {
  return (
    <FileUpload
      accept="image/*"
      onUploaded={(file) => callFn("setAvatar", { fileId: file.id })}
    />
  );
}
  • Presigned uploads — the client uploads straight to storage, not through your server
  • Local disk in dev, S3-compatible buckets in prod
  • R2, Backblaze B2, MinIO, or AWS S3 via one env var
  • File metadata lives in your typed schema, gated by the same policies
01

Direct-to-storage, signed

Pylon hands the client a short-lived presigned URL so the bytes go straight to the bucket — your server never proxies the upload, so large files don't tie up a worker. Downloads are gated through the same access policies as your rows.

02

The same code, any backend

Develop against the local filesystem with nothing to configure. In production, point one variable at R2, Backblaze, MinIO, or S3. No code changes — the storage driver is swapped underneath the same upload API.

03

Files are first-class rows

An uploaded file is a record in your schema with an owner, content type, and size — so you query it, gate it with a policy, and sync it like anything else. Owner-scoping is enforced on download, closing the IDOR class where any user can guess another's file id.

Build it on Pylon.

One framework for your schema, sync, auth, functions, realtime, and SSR. Free to start.