Temporary, resumable file transfers on your own Cloudflare account.
Share creates an upload link and a separate download link immediately, then transfers the file in resumable parts through a private R2 bucket. It is an OSS starter for teams that want a small transfer lane, not another collaboration suite.
- Demo: https://share.coey.dev
- Source: https://github.com/acoyfellow/share
- Deploy: https://deploy.workers.cloudflare.com/?url=https://github.com/acoyfellow/share
A single Worker backed by two Durable Objects and one local R2 bucket:
ShareSessionowns one temporary share, capability checks, multipart upload, download budget, and expiration.DemoQuotareserves bytes and limits anonymous share creation.- R2 stores completed bytes privately; the browser never receives a public storage URL.
- Turnstile gates anonymous creation using Cloudflare's official automated-test keys in local development.
Requirements: Bun and a Cloudflare-compatible browser.
bun install
bun run check
bunx wrangler dev --local --port 8796 \
--var TURNSTILE_SITE_KEY:1x00000000000000000000AA \
--var TURNSTILE_SECRET_KEY:1x0000000000000000000000000000000AAOpen http://localhost:8796.
For an automated browser pass while that server is running:
bun run browser:e2e- Choose a temporary file.
- Complete the visible test Turnstile challenge.
- Select Create secure links and upload.
- Copy the Share link into another tab. It contains only a read capability in the URL fragment.
- Observe upload readiness and download the finished file.
- Use the Manage link to resume an interrupted upload or remove the share.
You have now exercised the same capability boundary and R2 multipart path intended for a public demo deployment.
bun run typecheck
bun run test
bun run dry-run
bun run browser:e2e # with the local Worker running as in the tutorialThe test suite runs real Worker/Durable Object/R2 behavior under Cloudflare's Workers Vitest pool. It covers capabilities, quota reservation, multipart finalization, range downloads, aborts, and metadata non-disclosure.
The Deploy to Cloudflare button above creates your Worker, Durable Objects, and private R2 bucket from wrangler.jsonc.
During setup:
- Choose your Worker name and R2 bucket name.
- Create a Turnstile widget for your assigned Worker hostname (or your custom domain).
- Set
TURNSTILE_SITE_KEYand the secretTURNSTILE_SECRET_KEYfrom that widget. - Optionally set
PUBLIC_URLwhen you will use a custom hostname.
A fresh button deploy is reachable on its workers.dev hostname with Preview URLs disabled. If you attach a custom domain, switch to a single public surface in your generated repository:
Manual deployment is also supported:
bun install
bunx wrangler r2 bucket create share-files
bunx wrangler secret put TURNSTILE_SECRET_KEY
# Set TURNSTILE_SITE_KEY in wrangler.jsonc
bunx wrangler deployBefore operating a public hosted instance, read SECURITY.md and tune its limits for your cost and abuse posture.
All public limits are explicit Worker variables in wrangler.jsonc:
| Variable | Default | Meaning |
|---|---|---|
MAX_SHARE_SIZE_BYTES |
67108864 |
Maximum file size, 64 MiB |
MAX_ACTIVE_BYTES |
1073741824 |
Total currently retained or reserved bytes, 1 GiB |
MAX_CREATES_PER_HOUR |
5 |
Creation limit per coarse client key |
PENDING_TTL_SECONDS |
3600 |
Time allowed for incomplete uploads |
READY_TTL_SECONDS |
86400 |
Time completed downloads remain available |
DOWNLOAD_MULTIPLIER |
4 |
Download byte budget as a multiple of file size |
The uploader should not need to wait for a large transfer to finish before sharing intent. Share first creates a temporary record and two capabilities, then uploads chunks into R2. The read link can display pending progress and becomes downloadable after completion.
Public demo mode has no user accounts. It therefore uses capability security:
- The share link grants status and download access.
- The manage link additionally grants upload resume, cancellation, and deletion.
Capabilities live in URL fragments (#read=…, #manage=…), which are not sent to the server during navigation. Browser API calls move the selected capability into an Authorization: ShareCapability … header. The server stores only capability hashes.
An anonymous file-transfer site can otherwise become unbounded storage or distribution infrastructure. Share's defaults demonstrate the architecture while constraining cost and abuse:
- one temporary file per share;
- no public index or recipient email claims;
- private object storage and attachment-only downloads;
- Turnstile before storage reservation;
- exact retained-byte reservation in a Durable Object;
- request-time expiry enforcement plus cleanup alarms;
- bounded upload retry bytes and pre-debited download byte budgets.
For confidential or regulated file sharing, add identity-backed authorization, scanning, audit, retention, and operator processes rather than increasing public-demo limits.
| Method | Route | Required capability | Purpose |
|---|---|---|---|
GET |
/ |
None | Create-share interface |
POST |
/api/shares |
Valid Turnstile response | Reserve and create a pending share |
GET |
/share/:id#read=… |
Browser-held read capability | Viewer shell; fragment is not sent to the Worker |
GET |
/api/shares/:id/state |
Read or manage | Status and progress |
PUT |
/api/shares/:id/parts/:number |
Manage | Upload or retry one R2 multipart part |
POST |
/api/shares/:id/complete |
Manage | Finalize the object |
POST |
/api/shares/:id/abort |
Manage | Cancel pending transfer |
POST |
/api/shares/:id/delete |
Manage | Delete transfer/object |
GET |
/api/shares/:id/download |
Read or manage | Attachment download, including single byte ranges |
| File | Responsibility |
|---|---|
src/index.ts |
Worker pages and capability API routing |
src/share-session.ts |
Per-share Durable Object, multipart upload, expiry and downloads |
src/quota.ts |
Deployment-wide retained-byte and creation limits |
src/core.ts |
Capabilities, names, multipart and Range primitives |
src/turnstile.ts |
Turnstile server validation |
src/ui.ts |
Browser upload, viewer and download interface |
tests/ |
Core and Workers-runtime integration suite |
wrangler.jsonc |
Cloudflare bindings and configurable demo limits |
| Primitive | Role |
|---|---|
| Worker | Public UI and scoped HTTP API |
| Durable Objects | Share authority, cleanup alarms, exact quota authority |
| R2 | Private multipart object storage |
| Turnstile | Anonymous share-creation challenge |
MIT