CLI file sharing and link shortening. Backed by Cloudflare R2 + Workers.
Project description
share
CLI file sharing and link shortening with download tracking. Backed by Cloudflare R2 + Workers KV + Workers. Zero cost, full ownership.
Live at icecube.to ยท ๐ง.to
Why
Google Drive has no CLI. transfer.sh is dead. Presigned S3 URLs expire. This uploads a file or shortens a URL, gives you a short link, copies it to clipboard. Done.
$ share upload README.md --slug readme.md --public
https://icecube.to/readme.md (copied)
$ share link https://github.com/adriangalilea/share --slug gh --public
https://icecube.to/gh โ https://github.com/adriangalilea/share (copied)
$ share ls
Files
โโโโโโโโโโโโโณโโโโโโโโโโโโณโโโโโโโโโโโณโโโโโโโโโโโโโณโโโโโโณโโโโโโ
โ Slug โ Name โ Size โ Uploaded โ DLs โ Vis โ
โกโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉ
โ readme.md โ README.md โ 7.2 KB โ 2026-03-19 โ 15 โ pub โ
โโโโโโโโโโโโโดโโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโดโโโโโโ
Links
โโโโโโโโณโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโณโโโโโโโโโโโโโณโโโโโโโโโณโโโโโโ
โ Slug โ URL โ Created โ Clicks โ Vis โ
โกโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉ
โ gh โ https://github.com/adriangalilea/share โ 2026-03-19 โ 2 โ pub โ
โโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโดโโโโโโ
icecube.to/<slug>
$ share rm gh
Deleted https://github.com/adriangalilea/share (/gh)
This README is shared at icecube.to/readme.md.
Usage
share upload <file> # upload file, auto-generate slug
share upload <file> --slug <name> # custom slug
share upload <file> --public # show on landing page (default: private)
share upload <file> --name <name> # override download filename
share upload <file> --keep-metadata # skip EXIF/metadata stripping
share link <url> # shorten a URL
share link <url> --slug <name> # custom slug for short link
share link <url> --public # show on landing page
share ls # list all files and links
share rm <slug> # delete by slug, filename, URL, or r2_key
share setup # interactive first-time config
Uploads strip EXIF/metadata by default (images via Pillow, videos via ffmpeg).
Install
uv tool install git+https://github.com/adriangalilea/share.git
Architecture
CLI (Python) Cloudflare Free Tier
โโโโโโโโโโโโโโโโ boto3/S3 API โโโโโโโโโโโโโโโโโโโ
โ share CLI โ โโโโโโโโโโโโโโโโโโ โ R2 โ files (10GB free)
โ โ โโโโโโโโโโฌโโโโโโโโโ
โ โ CF Python SDK โ
โ โ โโโโโโโโโโโโโโโโโโ โโโโโโโโโโดโโโโโโโโโ
โ โ โ KV โ slug โ metadata
โโโโโโโโโโโโโโโโ โโโโโโโโโโฌโโโโโโโโโ
โ
Browser โ
โโโโโโโโโโโโโโโโ โโโโโโโโโโดโโโโโโโโโ
โ short link โ โโโโโโโโโโโโโโโโโโ โ Worker โ serves files,
โ โ โ (custom domain) โ tracks downloads,
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ landing page
The CLI uploads files to R2 and writes metadata to KV keyed by slug:<slug>. The Worker on your custom domain looks up slugs, streams files from R2 with range request support (for video/audio streaming), and increments download counters.
Every response carries a Content-Disposition header with the original filename so downloads keep their extension regardless of browser or OS (the slug in the URL has no extension; without this header some browsers save the file extensionless). Previewable types โ text/*, anything containing json/xml/javascript, image/*, audio/*, video/*, and application/pdf โ are served inline so the link still renders in-tab. Everything else (all archives: .7z, .zip, .tar, .gz, .rar, โฆ; binaries; unknown application/octet-stream) is served attachment and downloads with the correct name.
Self-hosting
Prerequisites
- Python >=3.12, uv
- Cloudflare account (free tier)
- Node.js (for worker deployment)
- A domain pointed to Cloudflare nameservers
1. Install the CLI
uv tool install git+https://github.com/adriangalilea/share.git
2. Create Cloudflare resources
You need two API tokens:
R2 API token (S3-compatible, for file uploads):
- Cloudflare dashboard โ R2 โ Manage R2 API Tokens โ Create
- Permissions: Object Read & Write
- Save the Access Key ID + Secret
CF API token (for KV + worker deployment):
- My Profile โ API Tokens โ Create Token
- Use template: Edit Cloudflare Workers
- Add permissions: Zone DNS Edit + Zone Read
- Save the token
3. Run setup
share setup
This verifies credentials, creates the R2 bucket and KV namespace, and writes config to ~/.config/share/config.toml.
4. Configure and deploy the worker
Clone the repo and edit worker/wrangler.toml:
name = "share"
main = "src/index.ts"
compatibility_date = "2026-03-19"
[[r2_buckets]]
binding = "R2"
bucket_name = "share"
[[kv_namespaces]]
binding = "KV"
id = "your-kv-namespace-id" # printed by share setup
[[routes]]
pattern = "yourdomain.com"
custom_domain = true
[vars]
SITE_NAME = "yourdomain.com"
Then deploy:
cd worker
npx wrangler deploy
5. Add your domain to Cloudflare
If not already done:
- Cloudflare dashboard โ Add a site โ your domain
- Update nameservers at your registrar to the ones Cloudflare gives you
- The worker deploy will create the DNS records automatically
- SSL/TLS โ Edge Certificates โ Always Use HTTPS โ ON
6. Upload
share upload myfile.pdf
# https://yourdomain.com/kX9mT (copied)
Config
~/.config/share/config.toml โ see config.example.toml.
| Key | Description |
|---|---|
cloudflare.account_id |
Cloudflare account ID |
cloudflare.r2_access_key_id |
R2 S3 API access key |
cloudflare.r2_secret_access_key |
R2 S3 API secret key |
cloudflare.api_token |
CF API token |
cloudflare.bucket |
R2 bucket name (default: share) |
cloudflare.kv_namespace_id |
Workers KV namespace ID |
urls.public_base |
Your domain (e.g. https://yourdomain.com) |
upload.strip_metadata |
Strip EXIF before upload (default: true) |
Cloudflare free tier limits
| Service | Limit | Usage |
|---|---|---|
| R2 | 10 GB storage, 1M writes/mo, 10M reads/mo, zero egress | File storage |
| Workers KV | 1 GB storage, 100K reads/day, 1K writes/day | File metadata |
| Workers | 100K requests/day, 10ms CPU/request | Serve files + landing page |
VPN note
R2's S3 endpoint uses TLS that some VPNs break. If uploads fail with SSL errors, bypass VPN for r2.cloudflarestorage.com.
KV schema
slug:<slug> โ file: { type?, name, size, content_type, uploaded_at, downloads, r2_key, slug, public }
slug:<slug> โ link: { type: "link", url, slug, created_at, clicks, public }
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters