Files
427e7578-d7bf-49c8-aee9-2dd…/README.md
2026-05-10 20:10:01 +00:00

3.1 KiB

Polly - P2P Poll App

A lightweight, real-time collaborative polling application that uses Yjs and WebRTC to allow multiple users to create options, vote, and see live results without a centralized database or back-end server.

🚀 Features

  • Real-time Collaboration: Instant synchronization of poll titles, options, and votes across all connected peers using CRDTs (Conflict-free Replicated Data Types).
  • P2P Connectivity: Uses WebRTC via y-webrtc for direct browser-to-browser communication.
  • Dynamic Voting: * Add new options on the fly.
    • Live-updating progress bars and vote tallies.
    • Automatic sorting of options by vote count.
  • Voting Deadline: A shared countdown timer (2 minutes) that locks the poll for all participants once expired.
  • Awareness & Presence: A status bar showing connection health and the number of active peers currently in the room.
  • Local Persistence: Uses y-indexeddb to save the poll state locally in your browser, ensuring data isn't lost if you refresh or lose connection.
  • No Setup Required: Unique "rooms" are created via URL parameters, making it easy to share a link and start a poll instantly.

🛠 Tech Stack

  • Language: TypeScript
  • State Management: Yjs (Shared data types: Y.Doc, Y.Map, Y.Text)
  • Networking: y-webrtc (WebRTC provider for Yjs)
  • UI: Vanilla DOM manipulation (No heavy frameworks like React or Vue)

💡 How It Works

  • Room Creation: When you open the app, it checks for a ?room= parameter. If none exists, it generates a unique ID and updates the URL.
  • State Synchronization: The y-webrtc provider connects users with the same room ID. Any change to sync.options or sync.votes is propagated to all users.
  • Local Reactivity: Components use .observe() and .observeDeep() on Yjs types to trigger a re-render of the UI whenever the shared state changes.
  • Voting: Votes are stored in a Y.Map where the key is the User ID and the value is the Option ID. This ensures each user can only have one active vote at a time.

You can simulate a second user by opening an incognito Tab.

🔧 Installation, Development and Deployment

  • Install dependencies:

    npm install yjs y-webrtc y-indexeddb

  • Development:

    npm run dev

  • Deployment:

    • The code currently uses an Y-Webrtc-Signaling-Server at localhost:4444 that starts with npm run dev for development.

    • To deploy the App, you need to set up a publicly available signaling server and set the address in the synx.ts. E.g. with Docker using the funnyzak/y-webrtc-signaling image:

      services:
          y-webrtc-signaling:
              container_name: y-webrtc-signaling
              image: funnyzak/y-webrtc-signaling:latest
              restart: always
              network_mode: bridge
              ports:
              - "4444:4444"
              dns: 8.8.8.8```