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.
- 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.
- File Size Support – Transfer files up to 500MB (configurable limit to prevent memory issues).
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 reassembled in the receiver's browser.
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)
git clone https://github.com/YOUR-USERNAME/WebDrop.git
cd WebDropUsing npm:
npm install --legacy-peer-depsOr using pnpm:
pnpm installCreate a .env.local file in the project root:
NEXT_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-keyNote: These values are found in Supabase Dashboard → Project Settings → API.
npm run dev
# or
pnpm devOpen http://localhost:3000 to view the app.
npm run buildThe 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
Files are chunked and transferred peer-to-peer, then reassembled in the receiver's browser memory (RAM).
Default limit: 500MB per file
This limit is set in lib/hooks/use-file-transfer.ts as the MAX_FILE_SIZE constant. You can increase it, but be aware:
- Larger files require more memory on the receiver's device
- Low-memory devices may crash when receiving large files
- Consider your users' typical device capabilities
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