Serein
Rust로 만든 가볍고 성능 좋은 Discord 전용 네이티브 클라이언트
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기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.