尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Simple peer-to-peer screen sharing with WebRTC and PeerJS
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗A deliberately small, open-source screen and file sharing service. Create a room, send a link, and let several participants share at once—no accounts, installs, or persisted room history.
Live demo: miseshare.vercel.app
If a connection fails, use the in-room connection check or icecheck (live tool) to isolate signaling, ICE candidate, data-channel, and media-path problems between two browsers.
Native WebRTC video tracks carry the 720p, 1080p, and 60 fps screen-sharing presets over encrypted browser connections. A configured TURN server can relay that encrypted traffic when a direct path is unavailable. A separate lossless text mode sends pixel-exact tile deltas over WebRTC data channels. File drops use a dedicated reliable data channel, begin only after each recipient accepts, and never upload file contents to the service. A small REST API stores temporary room admission and WebRTC signaling messages in PostgreSQL; it never receives screen, chat, audio, or file data.
The application is authored in strict TypeScript on Bun. TanStack Start and React 19 provide server rendering and file-based routing, Nitro serves the production app and API handlers, and shadcn's Base UI primitives sit underneath the custom Miseshare interface. Drizzle ORM owns the PostgreSQL schema and migrations.
bun install
bun run db:up
export DATABASE_URL='postgresql://miseshare:[email protected]:54329/miseshare'
export ADMIN_PASSWORD='choose-a-strong-local-password'
export ADMIN_SESSION_SECRET='generate-at-least-32-random-bytes'
bun run db:migrate
bun run dev
Open http://localhost:3000. Screen capture works on localhost; a deployed instance must use HTTPS.
Local development uses the PostgreSQL service in compose.yaml, bound to loopback on port 54329. DATABASE_URL is mandatory in every environment; there is no in-memory fallback. The schema is defined with Drizzle ORM in src/room-api/internal/schema.ts, with generated migrations tracked in drizzle/. The server applies pending committed migrations before accepting requests; a PostgreSQL advisory lock serializes concurrent serverless cold starts.
After changing the schema, generate and validate a migration before applying it:
bun run db:generate
bun run db:check
bun run db:migrate
Provision a Neon PostgreSQL database from the Vercel Marketplace and connect it to the project. Hosted production builds run committed Drizzle migrations under a PostgreSQL advisory lock before compiling and promoting the deployment. Preview and local Vercel builds skip production migrations. Keep schema changes backward-compatible with the currently deployed application so the migration and code promotion remain safe during rolling deployments. bun run build selects Nitro's Vercel preset when Vercel sets its build environment; outside Vercel it emits the Bun production server at .output/server/index.mjs for bun run start.
bunx vercel@latest --prod
Vercel serves the Nitro output and public assets from its CDN and runs the room REST API as stateless functions. Every invocation reads the same PostgreSQL room and signaling tables, so participants do not need to reach the same function instance. DATABASE_URL is mandatory on Vercel; the server fails fast instead of silently creating instance-local rooms.
| Variable | Default | Purpose |
|---|---|---|
PORT | 3000 | HTTP port |
HOST | 0.0.0.0 | HTTP bind address |
BASE_PATH | (empty) | Optional URL prefix, such as /previews/miseshare |
MAX_PARTICIPANTS | 12 | Deployment ceiling for total room participants, including the host (2–12) |
DATABASE_URL | (required) | PostgreSQL connection string; use Docker locally and Neon in production |
ADMIN_PASSWORD | (required) | Password for the read-only /admin database dashboard |
ADMIN_SESSION_SECRET | (required) | Independent random secret used to sign eight-hour admin sessions; use at least 32 bytes |
SECURE_COOKIES | production/Vercel: true; otherwise false | Require HTTPS for the admin session cookie |
TRUST_PROXY | false (Vercel configures one trusted hop) | Trust proxy-derived client IPs for rate limits; enable only behind a trusted proxy |
RATE_LIMIT_ENABLED | true | Enforce PostgreSQL-backed create, join, signal, and admin-login limits across instances |
REQUEST_LOGGING | production/Vercel: true; otherwise false | Emit structured request ID, status, path, and duration logs; server errors are always logged |
OBSERVABILITY_ENABLED | production/Vercel: true; otherwise false | Emit structured room lifecycle, signaling-failure, peer-state, and direct/TURN route events with HMAC-anonymized identifiers |
VITE_HEAD_HTML | (empty) | Trusted markup injected verbatim into the app <head> at server startup |
EMOTES_ENABLED |
When STUN_URLS contains multiple servers, browsers may query them concurrently; WebRTC does not guarantee a strictly sequential failover order.
VITE_HEAD_HTML accepts complete tags, such as a Meta Pixel <script> or a
site-verification <meta> tag. Treat it as trusted executable configuration:
never populate it from user input or another untrusted source. When configured,
the app page's content security policy adds the request nonce to injected script
and style tags and permits HTTPS origins needed by third-party analytics. Inline
event-handler attributes are intentionally unsupported. Leave it unset to inject
nothing and retain the strict default policy.
For reliable connectivity across restrictive NATs and corporate networks, deploy coturn with its REST API shared-secret mechanism, then set TURN_URLS and TURN_SHARED_SECRET. The app creates short-lived HMAC credentials per /config request and refreshes them before ICE recovery; the shared secret never leaves the server. A normal HTTP reverse proxy does not replace TURN because it cannot relay WebRTC media.
Global Twitch, BetterTTV, FrankerFaceZ, and 7TV emotes are available without provider credentials. Native Twitch emote metadata comes from the public Adam C Younis aggregate catalog. Provider URLs are never exposed to the browser. The server validates provider hosts and image types, applies size and timeout limits, caches the result, and serves it from /emotes/assets/:id. Disable this optional outbound provider access with EMOTES_ENABLED=false.
RTCPeerConnection data channels and media tracks communicate over encrypted direct or TURN-relayed paths.text-lossless-v1: it captures native RGBA pixels, compares 128 px tiles exactly, DEFLATE-compresses only changed tiles, and sends a periodic repair keyframe every 15 seconds. Frames are split into 48 KiB messages; a dropped or invalid delta triggers an immediate keyframe request before rendering resumes.src/room-api/index.ts is the server boundary for room admission and signaling storage. Its Drizzle/PostgreSQL implementation remains internal.src/signaling/index.ts is the browser boundary for REST room lifecycle, heartbeat, and signaling mailboxes.src/rtc/index.ts owns native WebRTC negotiation and recovery, fixed control/screen/diagnostics/drop channels, MessagePack serialization, and audio/video transceivers. src/drop/index.ts owns file offers, acceptance, chunking, backpressure, cancellation, and reconstruction.The full-mesh layout is ideal for small groups. Its bandwidth and connection count grow with every participant, so use an SFU for large audiences rather than raising the 12-person ceiling.
GET /health/live checks the process; GET /health/ready (and the compatibility endpoint GET /health) checks PostgreSQL readiness. Successful requests include an X-Request-Id header. Production logs include structured request timing plus anonymized room lifecycle and WebRTC connectivity events; turnUsed: true identifies relay usage without logging room codes or participant IDs. The /admin dashboard paginates in PostgreSQL, preserves its last successful snapshot during transient failures, and intentionally redacts password hashes, participant tokens, and signaling payloads.
Run the normal verification suite with bun run verify. To include the two-browser room flow and mobile-layout checks in Chromium and Firefox, install the browsers once and run the full suite:
bunx playwright install chromium firefox
bun run verify:full
Browser screenshots, videos, traces, and reports stay under .playwright/. CI also checks production dependency advisories and verifies that TanStack Router's generated route tree is current.
MIT
true| Load the global emote catalog and serve assets through the same-origin image proxy |
STUN_URLS | stun:stun.l.google.com:19302 | Comma-separated STUN URLs; non-STUN entries are ignored |
TURN_URLS | (empty) | Comma-separated turn: or turns: URLs for a coturn-compatible relay |
TURN_SHARED_SECRET | (required with TURN_URLS) | coturn REST authentication secret; never sent to browsers |
TURN_TTL_SECONDS | 3600 | Lifetime of generated TURN credentials, from 60 to 86400 seconds |
src/media/index.tssrc/room/index.tssrc/chat-ui/index.ts, src/emotes/index.ts, and src/ice-config/index.ts isolate browser chat behavior, the same-origin emote proxy, and ephemeral ICE configuration behind small public interfaces.