Simple, Fast, and Secure Peer-to-Peer File Transfer Tool
English | 简体中文 | 日本語 | 한국어 | Français | Español | Deutsch
🌐 Live Demo | 📖 Documentation | 🐛 Report Issues | 💡 Feature Requests
| 🚀 | Lightning Fast Powered by Cloudflare's global edge network with millisecond response times |
🔐 | 6-Digit Share Code Simple and memorable, with 2.18 billion combinations for security |
| 📦 | Large File Support Single file up to 25MB, perfect for everyday needs |
📝 | Multiple Formats Support for files, text, images, and various content types |
| 📚 | Batch Upload Support multiple files (up to 100) and images (up to 25) at once |
📦 | ZIP Download Download multiple files/images as a single ZIP package |
| ⏱️ | Auto-Deletion Automatically deleted 1 minute after download to protect privacy |
🆓 | Completely Free Based on Cloudflare's free tier, no credit card required |
| 🎨 | Beautiful Interface Modern UI design with exceptional user experience |
📱 | Responsive Design Perfect support for mobile, tablet, and desktop |
👉 Visit: https://f2f.icu
| Technology | Description |
|---|---|
| ⚡️ Cloudflare Pages | Frontend static website hosting with global CDN acceleration |
| 🔥 Cloudflare Workers | Serverless backend API with edge computing |
| 💾 Cloudflare KV | Key-value storage with native TTL support |
| 🎨 Tailwind CSS | Modern CSS framework for rapid UI development |
| 📝 TypeScript | Type-safe JavaScript superset |
- ✅ Node.js 16+
- ✅ Cloudflare account (free tier is sufficient)
- ✅ Git
-
Fork this repository
Click the
Forkbutton in the top right -
Connect to Cloudflare Pages
- Login to Cloudflare Dashboard
- Go to
Workers & Pages→Create application→Pages→Connect to Git - Select your forked repository
- Build configuration:
- Build command: Leave blank (or
npm run build) - Output directory:
public
- Build command: Leave blank (or
- Click
Save and Deploy
-
Configure KV Storage
- In Dashboard, go to
Workers & Pages→KV - Click
Create a namespace, name itf2f-transfers - Go back to your Pages project →
Settings→Functions→KV namespace bindings - Add binding:
- Variable name:
TRANSFERS - KV namespace: Select
f2f-transfers
- Variable name:
- Save and redeploy
- In Dashboard, go to
-
Done! 🎉
Visit the domain provided by Cloudflare
# Clone repository
git clone https://github.com/isnl/f2f.git
cd f2f
# Install dependencies
npm install
# Create KV namespace
wrangler kv:namespace create "TRANSFERS"
# Configure wrangler.toml
# Add the generated namespace ID to wrangler.toml
# Start local development server
npm run dev
# Visit http://localhost:8788Edit wrangler.toml:
name = "f2f-transfer"
compatibility_date = "2025-11-20"
pages_build_output_dir = "public"
[[kv_namespaces]]
binding = "TRANSFERS"
id = "your_kv_namespace_id_here" # Replace with your production KV ID
preview_id = "your_preview_kv_id_here" # Replace with your preview KV ID- Switch to Send tab
- Enter or generate a 6-digit share code (supports uppercase letters A-Z and numbers 0-9)
- Select content type:
- File: Click to upload or drag and drop (supports multiple files, up to 100, total ≤25MB)
- Text: Enter text content directly
- Image: Select image or Ctrl/Cmd + V to paste screenshot (supports multiple images, up to 25)
- Click Create Share
- Copy the share code or link and send to recipient
- Switch to Receive tab
- Enter 6-digit pickup code
- Click Get Content
- Download options:
- Single file: Auto-download
- Multiple files/images: Choose to download individually or as a ZIP package
- Text/Image: Direct preview display
⚠️ Content will be automatically deleted after 1 minute, please save promptly
graph LR
A[Sender Upload] --> B[Convert to Base64]
B --> C[Store in KV]
C --> D[Generate Share Code]
D --> E[Receiver Enters Code]
E --> F[Read from KV]
F --> G[Mark as Downloaded]
G --> H[Set 1 Minute TTL]
H --> I[Auto Delete]
-
Upload Phase
- File → Base64 encoding → Store in KV
- Default TTL: 1 hour (auto-delete after 1 hour if not downloaded)
-
Download Phase
- Verify share code → Read data
- Mark as downloaded → Update TTL to 1 minute
- Auto-trigger browser download (files) or display (text/images)
-
Cleanup Phase
- KV automatically deletes expired data based on TTL
- Zero maintenance cost
| Feature | KV Storage | R2 Object Storage | D1 Database |
|---|---|---|---|
| Single value size | 25MB ✅ | 5GB | 1MB (needs sharding) |
| TTL support | Native ✅ | ❌ Manual implementation | ❌ Manual implementation |
| Read/write latency | Very low ✅ | Low | Lower |
| Free tier | 100K reads/day ✅ | Requires credit card | 10 databases |
| Use case | Temporary file storage ✅ | Large file storage | Structured data |
| Item | Description |
|---|---|
| 🔢 Code Strength | 6 characters (A-Z, 0-9), ~2.18 billion combinations |
| ⏰ Data Retention | Not downloaded: 1 hour / Downloaded: 1 minute |
| Not recommended for sensitive information (passwords, IDs, etc.) | |
| 🔐 Transfer Security | Full HTTPS encryption |
- File Size: Maximum 25MB total
- File Count: Up to 100 files or 25 images per transfer
- Share Code Format: 6-digit uppercase letters or numbers (A-Z, 0-9)
- Data Retention:
- Not downloaded: Auto-delete after 1 hour
- Downloaded: Auto-delete after 1 minute
- KV Free Tier:
- 100,000 reads per day
- 1,000 writes per day
- Sufficient for personal use
Upload file or text
Request Parameters (FormData):
{
code: string, // 6-digit share code (required)
type: 'file' | 'text' | 'files' | 'images', // Content type (required)
content: string, // Content (required)
// - file: Base64 encoded file content
// - text: Plain text content
// - files: JSON array [{dataUrl, name, size, type}, ...]
// - images: JSON array [{dataUrl, name}, ...]
fileName?: string // File name (required when type=file)
}Response:
{
success: true,
code: string, // Share code
message: string // Status message
}Download file or get text
Request Parameters:
?code=ABC123 // 6-digit pickup code
Response:
{
success: true,
type: 'file' | 'text' | 'files' | 'images',
content: string, // Base64, text, or JSON array
contentType: string, // MIME type
fileName?: string // File name (returned when type=file)
}Edit functions/api/upload.ts:
const maxSize = 25 * 1024 * 1024; // Modify to your desired size (bytes)Upload TTL (not downloaded):
// functions/api/upload.ts
expirationTtl: 3600 // 1 hour = 3600 seconds, customizableDownload TTL (downloaded):
// functions/api/download.ts
expirationTtl: 60 // 1 minute = 60 seconds, customizable- ✅ Tailwind CSS on-demand loading
- ✅ Lazy loading icons (Lucide Icons)
- ✅ Responsive image preview
- ✅ Debouncing and throttling
- ✅ Edge computing (Cloudflare Workers)
- ✅ Global CDN acceleration
- ✅ Low-latency KV storage
- Enable Cloudflare's Brotli compression
- Configure custom domain with HTTPS
- Enable Cloudflare Analytics to monitor traffic
- Use Cloudflare Workers Analytics to monitor API performance
We welcome all forms of contributions! 🎉
- Fork this repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit changes (
git commit -m 'Add some AmazingFeature') - Push to branch (
git push origin feature/AmazingFeature) - Submit Pull Request
- 🐛 Report bugs
- 💡 Suggest new features
- 📖 Improve documentation
- 🎨 Optimize UI/UX
- ⚡️ Performance optimization
- 🌍 Multi-language support
- Follow TypeScript conventions
- Keep code clean and readable
- Add necessary comments
- Test features before submitting
Thanks to the following technologies and projects:
- Cloudflare Pages - Static website hosting
- Cloudflare Workers - Serverless computing platform
- Tailwind CSS - CSS framework
- Lucide Icons - Open source icon library
This project is licensed under the MIT License - see the LICENSE file for details
- 🐛 Report Issues: GitHub Issues
- 💡 Feature Suggestions: GitHub Discussions
- 📧 Email Contact: Via GitHub
Why not use R2 object storage?
R2 object storage requires credit card binding, while KV storage is completely free and ready to use. For temporary file transfers under 25MB, KV storage is sufficient with lower latency.
How to modify file size limit?
Modify the maxSize constant in functions/api/upload.ts. Note:
- KV single value maximum is 25MB
- Files over 25MB require R2 object storage
- Larger files take longer to upload/download
Is data really secure?
- ✅ All data stored on Cloudflare edge nodes with physical security
- ✅ Full HTTPS encrypted transfer
- ✅ Auto-deletion mechanism protects privacy
⚠️ Small probability of 6-digit code being guessed⚠️ Not recommended for highly sensitive information (passwords, private keys, etc.)
Why 1-minute deletion after download instead of immediate?
Provides error tolerance time for users:
- Avoids download failures due to network latency
- Allows users to re-download once
- 1-minute auto-deletion balances convenience and security
You can customize this time in the code.
Is the free tier sufficient?
More than enough for personal use:
- KV Reads: 100,000 per day
- KV Writes: 1,000 per day
- Workers Requests: 100,000 per day
For teams or high-frequency use, you may need to upgrade to a paid plan.
Can I self-host?
Absolutely! This project is open source, you can:
- Fork this repository
- Deploy to your own Cloudflare account
- Customize domain and configuration
- Have full control over data and service
Does it support batch upload?
✅ Yes! The current version supports batch upload:
- Multiple files: Up to 100 files, total size not exceeding 25MB
- Multiple images: Up to 25 images, total size not exceeding 25MB
- Download options: Download individually or as a single ZIP package
How to view usage statistics?
In Cloudflare Dashboard you can view:
- Workers Analytics: API call count, response time, etc.
- KV Metrics: Read/write count, storage usage, etc.
- Pages Analytics: Traffic, geographic distribution, etc.

