Watch streams together with voice and chat.
SocialTypeScript · JavaScriptGitHub @dsameendraOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Virtual watch-party: synced YouTube and Twitch, voice, chat and screen sharing in shared rooms.
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗Watch together, wherever you are. Voice, chat, synced YouTube, Twitch and Kick, and screen sharing in one shared room. Installs as an app on phones and desktops.
Live at nexuslounge.party.
I built it so my friends and I could watch League of Legends Worlds together, but it's general purpose: sports, premieres, VODs, movie nights.
| Phone | Phone: streams | Phone: landscape |
|---|---|---|
| Collapsed side panel | People | Room settings |
|---|---|---|
| Playlists and queue | Landscape with chat open |
|---|---|
| Choose where video plays (TV connected) | Phone player bar: More menu | Account |
|---|---|---|
Rooms and people
Watching
127.0.0.1:11470, or any address you set); links play straight in the browser when they can, and through Stremio when they can't (insecure http redirects, formats your browser can't decode, services that block browsers), which converts them to HLS that plays everywhere. Matroska plays as it is on Chrome and Edge, and HEVC/AC3/E-AC3 are used directly where your browser decodes them. Friends without Stremio watch a live feed from the owner's browser. Friends with Stremio tap to download the torrent themselves, in sync, with no load on the owner, or paste their own link or magnet to the same video (the size and length must match). Links stay in the owner's tab and are never sent to the room or the server, expired ones can be replaced in place, and error clips from link services are flagged. Chrome and Edge ask once to let the site reach devices on your network. Subtitles (tracks inside the video, files that came with a torrent, a file from your computer, or a search by title through OpenSubtitles) are chosen per person.Playback controls
Voice and chat
Phones and tablets
Desktop
\ key) to be fully immersed. Voice controls move into the header and an unread badge keeps you posted on chat.F fullscreen, M mute, and for controllers Space/K play and pause, ←/→ skip 5 seconds, J/L skip 10 seconds. Shortcuts are ignored while typing.Any screen
/account. Terms of Service and Privacy Policy are public at /terms and /privacy (use these URLs in the Discord developer portal).flowchart LR
B[Browser<br/>Next.js app] -- HTTPS --> W[web<br/>Next.js + Auth.js]
W -- signed token --> S[server<br/>Fastify + ws]
B -- WebSocket ticket --> S
B -- WebRTC --> L[(LiveKit)]
S -- grants and tokens --> L
apps/web Next.js app (UI, Discord login via Auth.js, thin API routes)
apps/server Fastify + ws (rooms in memory, LiveKit tokens, sync WebSocket)
packages/shared zod schemas, types and the sync maths shared by both
docs/ Railway notes and screenshots
Requirements: Node 22.18+ (the server runs TypeScript directly), pnpm 10+, and Docker only if you self-host LiveKit locally.
Setup
pnpm installcp .env.example .env and fill it in (below).pnpm dev, then open http://localhost:3000.pnpm dev starts the web app (port 3000) and the server (port 4000). For local voice, run pnpm livekit in another terminal (needs Docker), or use LiveKit Cloud instead.
DISCORD_CLIENT_ID and reset/copy the Client Secret into DISCORD_CLIENT_SECRET.http://localhost:3000/api/auth/callback/discord (add your production URL the same way).AUTH_SECRET with openssl rand -base64 32..env.example): pnpm livekit runs LiveKit in dev mode with key devkey and secret secret, at ws://localhost:7880.wss://….livekit.cloud) into LIVEKIT_URL and an API key/secret pair from Settings → Keys into LIVEKIT_API_KEY / LIVEKIT_API_SECRET.| Variable | Used by | Purpose |
|---|---|---|
DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET | web | Discord OAuth |
AUTH_SECRET | web, server | Session encryption and server token signing (must match) |
AUTH_URL | web | Public URL of the web app |
LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET | server | LiveKit connection and token minting |
NEXT_PUBLIC_SERVER_WS_URL | web | WebSocket URL of the server (wss://<server>/ws); the HTTP URL is derived from it |
SERVER_WS_URL | web | Optional runtime override of the above. Next bakes NEXT_PUBLIC_* values in at build time, this one is read when the app runs |
PORT | server | Server port (default 4000) |
ADMIN_SECRET | web, server | Optional. 32+ random characters, different from AUTH_SECRET; signs admin requests and the admin session cookie |
ADMIN_DISCORD_IDS | web, server | Optional. Comma-separated Discord user IDs allowed to open /admin |
ADMIN_TOTP_SECRET | web | Optional. Base32 key for the authenticator app used to unlock /admin |
AUTH_SECRET) and call the Fastify server, which verifies it. Joining a room returns a LiveKit token plus a room-scoped ticket for the sync WebSocket.packages/shared/src/protocol.ts).position, playing and a server timestamp. Clients estimate the server clock (median of ping samples) and compute the expected position locally. Drift is the median of the last few readings, small drift is fixed by gently changing playback speed, and seeks are rare and debounced. Add ?debug to a room URL to see the live numbers.pnpm typecheck
pnpm --filter @nexus/shared test # URL parsing, drift maths, live-edge helpers, tokens, sound cues
pnpm --filter @nexus/server test # spawns the server; permissions, guest approval, removal, moderation,
# late joiners, passwords, tickets, TV pairing over real WebSockets
CI runs the same checks plus a production build on every push.
Browser end-to-end suites (Chrome plus WebKit for the iPhone-style checks) live in e2e/: rooms, voice, push to talk, fullscreen, the queue and playlists, gestures, phone layouts and "nothing covers the Twitch player".
Two services built from the Dockerfiles in apps/server and apps/web, auto-deployed from main. LiveKit must be LiveKit Cloud, since Railway doesn't support UDP. Step-by-step instructions and config templates are in docs/railway-deploy.md.
Every server deploy or restart ends all rooms, because they live in memory. Keep the server at a single instance.
Copyright (C) 2026 dsameendra
Nexus Lounge is free software under the GNU Affero General Public License v3.0 (AGPL-3.0-or-later). You can use, modify and host it, but if you run a modified version as a service, you must make your version's source available to its users under the same license. Derivative works must stay open source.
If you like it and want to help with hosting costs, you can support it on Ko-fi. It is optional, and a star on the repo helps just as much.