The "Cross-Device" Problem
Have you ever been building a web application—maybe a registration form or an admin panel—and hit this specific roadblock?
The user needs to upload a photo, scan a document, or sign a canvas using their phone, but they are currently working on their desktop.
Usually, the "engineering" solution to this is surprisingly heavy:
- Build an API endpoint to receive the file.
- Set up a database or S3 bucket to store it temporarily.
- Force the user to log in on their mobile device.
- Implement a WebSocket or Polling mechanism to update the desktop UI when the upload is done.
That is a lot of infrastructure for a simple 30-second interaction. I wanted a better way.
So, I built React State Warp.
🚀 What is React State Warp?
React State Warp is a lightweight React Hook that creates a secure, peer-to-peer (P2P) wormhole between devices.
It allows you to generate a QR code on one device (Host), scan it with another (Client), and instantly sync React State between them.
- Zero Backend: Powered by WebRTC (PeerJS). Data travels Device-to-Device.
- Zero Database: Nothing is stored on a server.
- Instant Sync: Text, JSON, and even Binary data sync in milliseconds.
🪄 The Magic: Syncing Files without a Server
The hardest part of P2P is usually handling binary data. Most libraries break when you try to send a JavaScript File object.
I implemented a custom serializer that automatically detects File, Blob, or Uint8Array in your state, converts them efficiently, chunks them if necessary, and reconstructs them on the receiving device as a valid File object.
This means you can do this:
// 📱 On Mobile:
<input type="file" onChange={(e) => send({ avatar: e.target.files[0] })} />
// 💻 On Desktop:
// 'data.avatar' instantly becomes a File object you can display!
<img src={URL.createObjectURL(data.avatar)} />
🛠️ How to use it
It is designed to be a "Headless" hook, meaning you have full control over the UI.
-
Install
npm install react-state-warp peerjs -
Implement the Hook
import { useStateWarp } from 'react-state-warp'; import QRCode from 'react-qr-code'; function App() { // Initialize state like standard useState const { data, send, connectionLink, status } = useStateWarp({ text: '', file: null }); return ( <div className="card"> <h1>Status: {status}</h1> {/* Inputs are automatically synced */} <input value={data.text} onChange={(e) => send({ ...data, text: e.target.value })} placeholder="Type here..." /> {/* Show QR Code for the other device to join */} {connectionLink && ( <div className="qr-box"> <QRCode value={connectionLink} /> <p>Scan to join!</p> </div> )} </div> ); }
🛡️ Handling the "Real World" (NATs & Firewalls)
One of the biggest pain points with WebRTC is connecting devices that are on different networks (e.g., WiFi vs. 4G).
React State Warp comes pre-configured with public Google STUN servers. This ensures that in 95% of cases, the connection punches through NATs and Firewalls automatically without you needing to configure ICE servers manually.
📦 Try the Demo
I included a complete "Identity Verification" playground in the repository. It simulates a real-world flow where a user starts a profile on Desktop and finishes verification on Mobile.
I would love to hear your thoughts! If you find this useful or interesting, dropping a Star ⭐ on GitHub would mean the world to me.
Let me know what you think in the comments below! 👇
Top comments (0)