How One Developer Recreated AirDrop Using Just JavaScript
SnapDrop.net

Have you ever used AirDrop on iPhone or Mac?

Okay, If you haven’t then can you imagine seamlessly sharing files between phones or a laptop at the tap of a button?

SnapDrop.net, created by Robin Linus, lets you directly share files between any device with a browser. Doesn’t matter if it’s between iPhone and Android or a tablet with a PC.

And no uploading to and downloading from the cloud needed. 😲

So how the heck does it work?

After analyzing it line by line, I figured out its brilliant architecture. In this post I’ll show you how it works.

Use This New Technology

Knowing this technology could set you apart from other engineers who haven’t yet explored what it has to offer.

This awesome technology is WebRTC (Web Real-Time Communication) and it only came out a few years ago. Its data channel enables SnapDrop to send bytes (even audio and video!) directly from one peer to another.

(Think of a peer as a device, like your phone or laptop)

However, WebRTC can’t connect two users without some help. It needs a signaling server, in other words, something to discover other peers and show it how to connect.

WebRTC is Impossible To Use Without This

Web Architecture

ICE (Interactive Connectivity Establishment) is how a computer can draw a map from the internet to itself when it doesn’t have a public IP address. This is due to NAT (Network Address Translation) that happens between your router and computer.

Once the map has been made, you’ll have to find some way for these two devices to share their maps with each other. SnapDrop does this through a NodeJS server that communicates between each peer using WebSockets — another awesome protocol.

Now you’re probably thinking, is this secure?

Okay, But How Do You Secure This Thing?

WebRTC in transit encrypts its data by default. That’s cool and all but you also probably don’t want to be sharing files with random people.

SnapDrop only shares the ICE between two computers with the same IP address — meaning they’re on the same network/wifi.

It does this by creating rooms for each IP address and differentiates devices by generating a unique id.

You might not want to use this app while on public WiFi since then anyone could send files to you. But in this pandemic, who’s going outside anyway? 🤷‍♀️

The code snippet above makes an interesting choice by storing the peers in an object on the server class. Normally you would expect a database to be used but this might be to simplify things and the app probably doesn’t have a lot of traffic.

A Familiar User Interface and User Experience

SnapDrop Icons

The style is almost exactly like AirDrop. Each device has a fun name and an icon to help distinguish each peer. Not only that but its also a progressive web app which gives it a few nice features like:

Feels like a native app

Notifications

Live Updates

What If The Device Doesn’t Support WebRTC?

By now most devices/browsers support WebRTC but in the event that they don’t, SnapDrop has a fallback! In this case it uses the already established WebSocket connection to send the file data.

However, this is less efficient and less secure because the data needs to first go to the server and before it reaches its final destination.

Event-Driven Code Style

The code base is completely event-driven. You use this style when you want to decouple services from each other and allow processing as actions occur.

This compliments WebRTC and WebSockets because they’re also event-driven. When a message comes in, or a new peer joins, or a file wants to be sent — that’s an event.

It’s really tough to follow at first because its not a linear process. Here’s the class for registering and firing events.

Check Out The Code Yourself

I hope you learned something today! If you want to explore the code for yourself, here’s the github repository.

The creator was also kind enough to create a docker compose file so that you could run and host this yourself. I wonder how many people are running their own SnapDrop instance?

Thank you for reading, and I’ll catch you in the next one!
['Abdisalan Mohamud']
['WebRTC', 'Airdrop', 'JavaScript', 'Websocket', 'Programming']