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.
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
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.
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.
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.