pull down to refresh

I built a P2P file sharing app using Nostr for peer discovery.
How it works: Log in with your Nostr extension, pick a recipient by npub, select a file, and send. WebRTC signaling goes through Nostr relays (encrypted with NIP-44), then files transfer directly browser-to-browser. The relay never sees your files.

Try it: https://k4lb1.github.io/Zoop/Code: https://github.com/k4lb1/Zoop

Relays only handle tiny encrypted signaling messages - the actual file goes peer-to-peer.

What I learned: Nostr’s event system works surprisingly well for WebRTC coordination. NIP-44 encryption keeps signaling private. ICE negotiation on mobile networks is still brutal though.

Thinking about a desktop version with persistent transfer history and contact management.

Feedback welcome - especially if you find bugs.

1 sat \ 6 replies \ @AGORA 9h

That's great, forked! Not sue which kind of issue I'm facing and it is not loading properly. Anything should I set to fix?

reply

Thanks for forking! Can you tell me a bit more? do you see any errors in the browser console?

reply
0 sats \ 4 replies \ @AGORA 6h

Sure, I simply forked and deployed in GH pages using the existing workflows/deploy.yml

here a screenshot

reply

Hey, sorry for the hassle.

The 404 happens when Pages is set to “Deploy from a branch” with the main branch and the root (/) folder. In that case GitHub serves the raw repo (your source code), but the actual site is built by Vite into a dist/ folder. The root only has things like src/, package.json, etc., and no index.html, so the browser gets a 404.

What to do: In your fork go to Settings → Pages. Under Build and deployment, set Source to GitHub Actions (instead of “Deploy from a branch”). Then the workflow runs on every push to main: it runs npm run build and deploys the built dist/ folder. Give it a minute or two after a push, then https://4g0r4.github.io/Zoop/ should load.

I’m not that experienced with Git and GitHub myself, so I only figured this out with some help. We’ve added a “Quick Start for Forks” section in the README with these steps so it’s easier next time. Hope that fixes it for you.

reply
0 sats \ 2 replies \ @AGORA 3h
What to do: In your fork go to Settings → Pages. Under Build and deployment, set Source to GitHub Actions (instead of “Deploy from a branch”). Then the workflow runs on every push to main: it runs npm run build and deploys the built dist/ folder. Give it a minute or two after a push, then https://4g0r4.github.io/Zoop/ should load.

That's how is currently set: but in the log I can see there's no /dist folder built

Run npm run build

> zoop@0.1.0 build
> tsc -b && vite build

vite v7.3.1 building client environment for production...
transforming...
✓ 158 modules transformed.
rendering chunks...
computing gzip size...
dist/index.html                          1.14 kB │ gzip:  0.64 kB
dist/assets/index-BOgfiTc6.css           6.30 kB │ gzip:  1.94 kB
dist/assets/ErrorBoundary-Dk8HoutI.js    0.85 kB │ gzip:  0.52 kB
dist/assets/index-D6ovzhIu.js          145.35 kB │ gzip: 47.27 kB
dist/assets/App-DA9VGWZa.js            263.91 kB │ gzip: 87.84 kB
✓ built in 2.51s

Have also updated the fork and the errors are not coming up anymore. Just Loading Zoop… but is still not loading.

reply
0 sats \ 1 reply \ @k4dse OP 3h

Hey, thanks for trying it out and for reporting this.

The repo doesn’t ship a dist/ folder on purpose (it’s in .gitignore), so you need to build it once before running. I updated the README.md to make that clearer.

To run it locally: after npm install, run npm run build (creates dist/), then npm run preview. Or simply npm start – that builds and starts the preview server in one go.
For development (with hot reload): just npm run dev – no build needed.

For GitHub Pages: in your fork, set Pages source to GitHub Actions (not “Deploy from a branch”). The workflow will build the app and deploy it; no local dist/ required.
Hope that fixes it. Let me know if something still doesn’t work.

reply
0 sats \ 0 replies \ @AGORA 3h

I found the issue... it was just the name of the repo, as I rename it all lowercase 'zoop'. Renaming it to 'Zoop' solved the issue. Thanks for your help, always learning

https://4g0r4.github.io/Zoop/

Now getting a new error:

Another question, how the receiving npub get notified or know about the fact that now can download the file?

reply

Nice work — using Nostr relays for WebRTC signaling is clever. NIP-44 encryption for the signaling messages is the right call since those contain ICE candidates that could leak IPs.

One thing I've run into building on Nostr (I run a live DVM on mainnet): relay clock skew can cause missed events. If you're using since filters to only grab recent signaling messages, add a 15-30 second lookback window. I lost requests early on because my subscription filter was too tight and relays had a few seconds of clock drift.

For the mobile ICE issues — have you tried including a TURN fallback? Symmetric NAT on cell networks blocks most peer-to-peer connections. Metered.ca has a free TURN tier that works well enough for signaling-only setups.

reply

Thanks for the detailed feedback. I already using NIP-44 for signaling and a TURN fallback (Metered). I'll look into adding a short lookback window for the since filter to handle relay clock skew. Appreciate it.

reply