Peer-to-peer file transfer via WebRTC — React 19, .NET 9, SignalR, Docker
| QR Pairing | Connected | Dark Mode |
|---|---|---|
![]() |
![]() |
![]() |
ArsDrop is a peer-to-peer file transfer tool that works directly between browsers. Files go straight from one device to another through an encrypted WebRTC connection — nothing is stored or passes through any server. Scan a QR code to pair devices, then send files of any size instantly.
- React 19 with TypeScript and Vite
- .NET 9 with SignalR
- Ant Design for UI components
- xUnit for unit testing (28 tests)
- Docker for containerization
- Peer-to-peer file transfer via WebRTC DataChannel
- QR code pairing with automatic session refresh
- Real-time text sharing between devices
- Chunked file streaming with ACK-based reliability
- Transfer progress tracking per file
- Pause and resume file transfers
- Drag-and-drop file upload
- Screen Wake Lock to keep devices active during transfer
- Dark/Light mode
- i18n: Portuguese, English, Spanish
- Automatic reconnection with session persistence
- 256-bit cryptographic session tokens
- Rate limiting (10 creates/min, 30 validates/min per IP)
- Atomic session invalidation (only first receiver succeeds)
┌──────────────┐ ┌──────────────────┐
│ │ SignalR (Signaling) │ │
│ Device A │ <────────────────────────────> │ ArsDrop API │
│ │ │ .NET 9 │
└──────┬───────┘ └──────────────────┘
│ ▲
│ WebRTC DataChannel (P2P) │
│ <─────────────────────────────────> │
│ Files never touch server │
│ │
┌──────┴───────┐ SignalR (Signaling) ┌───────┴──────────┐
│ │ <────────────────────────────> │ │
│ Device B │ │ ArsDrop API │
│ │ │ │
└──────────────┘ └──────────────────┘
Backend:
ArsDrop.Api/
├── Controllers/ -> REST endpoints (create/validate session)
├── Enums/ -> Device role enum
├── Hubs/ -> SignalR hub (WebRTC signaling + authorization)
├── Models/ -> DTOs
├── Services/ -> Token generation and validation
├── Store/ -> In-memory session store with TTL
└── Extensions/ -> CORS, rate limiting
ArsDrop.Tests/ -> 28 unit tests (xUnit, NSubstitute, FluentAssertions)
Frontend:
src/
├── components/
│ ├── stages/ -> QrStage, ConnectingStage, ConnectedStage, FailedStage
│ ├── panels/ -> ConnectionPanel, FileTransferPanel
│ ├── drawers/ -> TransferSection, ShareSection
│ ├── layout/ -> PageLayout
│ └── ui/ -> CustomHeader, CustomQrCode, FileUpload
├── contexts/ -> Connection, Theme, Locale
├── hooks/ -> useOriginConnection, useFileOrigin, useQrCode, etc.
├── pages/ -> Home
├── i18n/ -> Locales (pt, en, es)
└── services/ -> API client
- Clone this repository
git clone https://github.com/AdrianoReusSavi/arsdrop.git - Enter the project folder:
cd arsdrop
Backend:
cd backend
dotnet run --project ArsDrop.ApiFrontend:
cd frontend
cp .env.example .env
npm install
npm run devdocker-compose up --build- Frontend: http://localhost:3000
- Backend: http://localhost:5041
cd backend
dotnet test- Fork this repository
- Create a branch with your feature:
git checkout -b my-feature - Commit your changes:
git commit -m 'feat: My new feature' - Push your branch:
git push origin my-feature
This project is under the MIT license. Take a look at the LICENSE file for more details.


