Secure, peer-to-peer file sharing powered by WebRTC.
WebDrop enables high-speed, direct file transfers between browsers without uploading to any central server. Your files go straight from sender to receiver using encrypted WebRTC data channels, ensuring privacy and speed.
- True Peer-to-Peer Transfer – Files are sent directly between users using encrypted WebRTC data channels. No files touch our servers.
- Memory-Efficient Streaming – Files are streamed directly to disk in modern browsers, eliminating memory issues even with large files up to 2GB.
- Room-Based Connections – Create or join private rooms using an 8-character room ID.
- Real-Time Presence – See who's online in your room with live status updates (Connecting, Live, Offline).
- Secure Authentication – Sign up and log in securely using Email or GitHub OAuth.
- Profile Management – Update your username and profile picture with client-side image resizing.
- Custom Avatars – Upload profile pictures stored securely in Supabase Storage.
- Robust Connection Handling – Gracefully handles page refreshes, browser disconnects, and reconnections.
WebDrop is built as a modern, serverless web application using Next.js and Supabase:
| Component | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| Language | TypeScript |
| Authentication | Supabase Auth (Email + GitHub OAuth) |
| Database | Supabase Postgres |
| Real-Time | Supabase Realtime (Presence & Broadcast) |
| Storage | Supabase Storage (Avatar uploads) |
| P2P Transfer | WebRTC (RTCPeerConnection, RTCDataChannel) |
| UI Framework | React 19.2 |
| Styling | Tailwind CSS 4 + shadcn/ui components |
| Icons | Lucide React |
| Package Manager | npm / pnpm |
- Authentication – Users sign up or log in via Supabase Auth (Email or GitHub).
- Room Creation/Join – Users create a new room or join an existing one with a room ID.
- Presence & Signaling – Supabase Realtime manages user presence and broadcasts WebRTC signaling messages (offers, answers, ICE candidates).
- WebRTC Connection – Direct peer-to-peer connections are established between browsers.
- File Transfer – Files are chunked and sent over encrypted WebRTC data channels, then streamed directly to disk as they arrive.
Signaling Flow: ``` User A (Initiator) Supabase Realtime User B (Responder) | | | |--- Broadcast Offer -------->|------ Forward Offer ----->| | | | |<----- Forward Answer -------|<----- Broadcast Answer ---| | | | |<---- Exchange ICE Candidates via Supabase Realtime ---->| | | | |============ WebRTC Direct Connection Established ========| | | | |<========= Encrypted File Transfer (P2P) ===============>| ```
- Node.js 18+ and npm or pnpm
- A Supabase account and project (supabase.com)
- (Optional) A GitHub OAuth App for GitHub authentication
- Go to supabase.com and create a new project.
- Note your Project URL and Anon Key from Project Settings → API.
Navigate to the SQL Editor in your Supabase dashboard and run the scripts in the /scripts directory in order:
001_create_tables.sql– Createsprofiles,peers, androomstables002_create_policies.sql– Sets up Row Level Security policies003_handle_new_user_trigger.sql– Auto-creates profile on user signup004_handle_updated_at_trigger.sql– Auto-updatesupdated_attimestamps005_add_peers_profile_fkey.sql– Adds foreign key constraint to peers table006_enable_realtime.sql– Enables Realtime onpeerstable007_avatar_storage.sql– Createsavatarsstorage bucket with policies008_sync_username_trigger.sql– Syncs username changes from profiles to peers
- Go to Authentication → Providers in Supabase.
- Enable GitHub provider.
- Create a GitHub OAuth App at github.com/settings/developers:
- Authorization callback URL:
https://[YOUR-PROJECT-REF].supabase.co/auth/v1/callback
- Authorization callback URL:
- Copy the Client ID and Client Secret to Supabase.
- Go to Authentication → URL Configuration in Supabase.
- Set Site URL to your production URL (e.g.,
https://webdrop.vercel.app) orhttp://localhost:3000for local dev. - Add Redirect URLs:
http://localhost:3000/**(local development wildcard)https://your-production-domain.com/**(production wildcard)
```bash git clone https://github.com/YOUR-USERNAME/WebDrop.git cd WebDrop ```
Using npm: ```bash npm install --legacy-peer-deps ```
Or using pnpm: ```bash pnpm install ```
Create a .env.local file in the project root:
```bash NEXT_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key ```
Note: These values are found in Supabase Dashboard → Project Settings → API.
```bash npm run dev
pnpm dev ```
Open http://localhost:3000 to view the app.
```bash npm run build ```
The app can be built without environment variables (useful for CI/CD), but it requires valid Supabase credentials at runtime.
WebDrop is optimized for deployment on Vercel:
- Push your code to GitHub.
- Import the repository in Vercel.
- Add environment variables:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEY
- Deploy!
Vercel will automatically detect Next.js and configure the build.
WebDrop can be deployed to any platform that supports Next.js:
- Netlify – Use the Next.js plugin
- Cloudflare Pages – Use
@cloudflare/next-on-pages - Self-hosted – Use
npm run build && npm run start
Currently, WebDrop does not include automated tests. Testing is done manually during development.
If you'd like to contribute tests, see CONTRIBUTING.md for guidelines.
``` WebDrop/ ├── app/ # Next.js App Router pages │ ├── auth/ # Authentication pages (login, signup, callback) │ ├── profile/ # User profile page │ ├── room/ # Room page for P2P transfers │ ├── api/ # API routes │ ├── layout.tsx # Root layout │ └── page.tsx # Landing page ├── components/ # React components │ ├── ui/ # shadcn/ui components │ ├── file-transfer-panel.tsx │ ├── header.tsx │ ├── footer.tsx │ ├── peer-list.tsx │ └── room-manager.tsx ├── lib/ # Utilities and business logic │ ├── hooks/ # React hooks │ │ ├── use-file-transfer.ts │ │ └── use-room.ts │ ├── supabase/ # Supabase client setup │ ├── webrtc/ # WebRTC logic (signaling, file transfer) │ ├── types/ # TypeScript type definitions │ └── utils.ts # Utility functions ├── scripts/ # Supabase SQL migration scripts ├── styles/ # Global styles ├── public/ # Static assets ├── next.config.mjs # Next.js configuration ├── tsconfig.json # TypeScript configuration └── package.json # Dependencies and scripts ```
WebDrop uses streaming technology to efficiently handle large files up to 2GB:
File size limit: 2GB per file
Files are streamed directly to disk using the File System Access API:
- Zero memory overhead – chunks are written to disk as they arrive
- Users choose save location before transfer starts
- Memory usage remains constant regardless of file size
- Perfect for large files up to 2GB
Supported browsers:
- Chrome/Edge 86 or later
- Safari 15.2 or later
Unsupported browsers will receive an error message when attempting to receive files. Users should upgrade to a modern browser to use WebDrop's file transfer feature.
The limit is set in lib/hooks/use-file-transfer.ts as the MAX_FILE_SIZE constant.
We welcome contributions! Please read CONTRIBUTING.md for guidelines on:
- Setting up your development environment
- Code style and conventions
- Submitting pull requests
- Reporting issues
This project is open source and available under the MIT License.
- GitHub: github.com/jomzxc/WebDrop
- Issues: github.com/jomzxc/WebDrop/issues
- Check browser console for WebRTC errors
- Ensure both users are in the same room
- Verify Supabase Realtime is enabled on the
peerstable - Check that firewall/NAT allows WebRTC connections
- Verify environment variables are set correctly
- Check Supabase redirect URLs include your domain
- For GitHub OAuth, ensure callback URL matches Supabase settings
- Verify Supabase Storage bucket
avatarsexists - Check storage policies allow authenticated users to upload
- Ensure file is under storage size limits
Built with ❤️ using Next.js, Supabase, and WebRTC