Library / SDK
99percentpeople/weblink avatar
99percentpeople/weblink

Weblink, a WebRTC workspace that adds desktop control to browser chat

Control your desktop from a browser, with P2P chat, file sharing, voice, video, and screen sharing powered by WebRTC.

691 stars66 forksTypeScriptMIT

At a glance

What is it?
Weblink is a WebRTC workspace offering chat, file sharing, voice, video, screen sharing and remote desktop control, delivered as a web app that needs no install and a Tauri desktop app for Windows. It suits people who want to reach a colleague's machine over peer connections rather than through a hosted remote desktop service, and the desktop half is currently Windows only.
Who is it for?
Adopt Weblink if you want peer-to-peer chat, file transfer and remote control that work from a browser without a client install, since the web app and the desktop app share the same interface and code, with the desktop app adding native capture, input, clipboard and window control. Do not adopt it for a mixed platform fleet today, because the supported desktop target is Windows 10 22H2 or Windows 11 on x64 with WebView2 120 or newer.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One interface, two runtimes: browser and Tauri desktop app

Weblink is described as a WebRTC workspace for chat, file sharing, voice, video and remote control, and the tagline is Share more. Install less. The web app works without installing a native client, while the desktop app reuses the same interface and application code and adds native screen capture, remote input, system clipboard access and desktop window controls.

That reuse is the structural decision. It means the feature set you see in a browser is the same feature set you get on a Windows desktop, with the differences confined to the capabilities table in the README. The web version stores files in IndexedDB by default and mounts a real directory where the browser supports it, while the desktop version uses a local directory by default and keeps IndexedDB as an option. Browser capture becomes native display and window capture with supported system audio on the desktop side.

The topics list the technologies in play: WebRTC, P2P, remote-desktop, tauri-app, pwa and webapp. The app is installable as a PWA where the browser supports it, and the desktop build ships a tray icon, launch at login, close behaviour and native notifications.

The supported desktop target is narrow, and the README says so plainly: Windows 10 22H2 or Windows 11 on x64, with WebView2 120 or newer.

Rooms with a password, and who may take control

Getting started is four steps. You open webl.ink or launch the desktop app, choose a display name and a room ID, optionally set a room password, then join the same room from another device with that password and invite others with a room link or a QR code.

The permission model for remote control is where the design is most deliberate. To control a remote computer, you run the desktop app there and request control from its participant or shared-display actions on another device. The host then either approves the request or falls back on a previously saved allow rule. A request can start display sharing after approval, but window shares stay view-only.

That distinction is a sensible security boundary. Full control of a machine, which includes remote input, is a different thing from watching a window, and the tool treats them as different permissions rather than as one toggle.

Per-client and per-room settings cover remote-control requests, access to shared files and automatic downloads, and Windows notifications support inline replies and request approval, so an approval prompt can be answered without leaving the notification. Message, control-request, speed-test and completed-transfer notifications are configurable with previews and sound.

File library, chunked transfers and content deduplication

The file side is the most developed part of the feature list. You import files or folders through a picker or drag and drop, send them from chat or the library, and folders are packaged as ZIP archives. Transfers can be tracked, paused, resumed, retried or cancelled, and the transfer reuses cached chunks and content you already have.

The local library is content-deduplicated with explicit sharing controls, and a shared file list is available across rooms. You can browse a connected member's shared files with search, sorting, previews and batch downloads, and those downloads enter the library and task list without adding chat messages, which keeps a busy transfer from turning into a chat scroll.

Downloads are on request by default, and small-file automatic downloads can be enabled per room with a shared size limit in Transfer settings. There is a migration path as well: old IndexedDB files and resumable chunks are migrated automatically with progress feedback, and the old file database is removed only after the new data has been verified.

Conflict handling on save is thorough too. You save a batch to one destination directory, resolve name collisions with overwrite, skip or keep both, and apply the choice to all remaining conflicts, with progress and cancellation controls on imports and saves.

A workspace monorepo with Rust crates behind the Tauri shell

The repository is a large monorepo and the layout tells you where the work is. The root package.json defines a Bun workspace with apps/*, packages/* and servers/*, and pins the package manager to [email protected] with an override for the same version. There are separate dev scripts for the web app, the marketing site, the desktop app and the websocket server, plus a long list of end-to-end suites for protocol, recovery, native screen, playback, transfer, vfs, cache and clipboard.

The Rust side is small and specific. The Cargo workspace has four members, apps/desktop/src-tauri plus three crates for desktop capture, desktop input and desktop accessibility, and it patches two crates from the project's own rust-sdks repository at a pinned revision.

The servers directory holds a websocket server and a websocket worker, and the compose file wires them to the web app through an nginx image. The container build is a three-stage image: bun for install with a frozen lockfile, bun for the build, and nginx:alpine to serve the built web app, with an entrypoint that renders the nginx configuration template and an SSL directory mounted for certificates.

Self hosting the signal server with STUN and TURN passed in

The docker-compose file shows how a self-hosted deployment is assembled. The weblink service builds from the repository Dockerfile, takes the websocket URL and the STUN server list as build arguments, publishes port 8080 for HTTP and port 443 for HTTPS, and takes an ENABLE_SSL environment flag that defaults to false, with a directory of SSL certificate files mounted. It depends on the ws-server service, which is built from servers/weblink-ws-server, runs with LOG_LEVEL=info and publishes port 9000.

The build arguments are the part to understand:

yaml
      args:
        # Set your public websocket url here, example:
        - VITE_WEBSOCKET_URL=ws://192.168.8.100:8080/ws
        - WEBLINK_STUN_SERVERS=stun:stun.l.google.com,stun:stun1.l.google.com

The websocket URL is baked into the built web app, so it is a build-time decision rather than a runtime setting, and changing it means rebuilding. The STUN server list is configurable in the same way, and a TURN server list is passed as a separate build argument in the Dockerfile.

That is the honest shape of a WebRTC deployment. Peer connections need a signalling channel, which is the websocket server, and a way to traverse NAT, which is STUN and, in harder networks, TURN. A self-hosted install therefore means running the signalling server and deciding on your own relay infrastructure, and the sample points at public Google STUN servers.

Browser limits, Windows limits and a very recent release history

The README is candid about the boundaries. Native system audio and input features depend on OS capabilities, and browser media capture, clipboard access, notifications and PWA integration depend on browser support and permissions, with the instruction to use HTTPS or localhost for browser capture, since a secure context is required.

The desktop app narrows the platform further. The installer sets up WebView2 when needed, while the portable ZIP requires WebView2 120 or newer and its weblink-portable marker beside the executable. Development CI produces a weblink-windows-x64 executable artifact, which tells you the desktop build pipeline is currently Windows only.

The release history is very recent. Version 1.1.0 on 2026-10-13, 1.1.1 on 2026-10-15 and 1.2.0 on 2026-10-18, with the last push to the public branch on 2026-10-20. The homepage is webl.ink, and the licence is MIT.

The combination to keep in mind is that this is a fast-moving project with a young version line, so an upgrade can bring behaviour changes in the approval rules or the transfer path, and the room password plus saved allow rule model deserves a deliberate review before it is used for unattended access.

Editorial conclusion

Adopt Weblink if you want peer-to-peer chat, file transfer and remote control that work from a browser without a client install, since the web app and the desktop app share the same interface and code, with the desktop app adding native capture, input, clipboard and window control. Do not adopt it for a mixed platform fleet today, because the supported desktop target is Windows 10 22H2 or Windows 11 on x64 with WebView2 120 or newer. Before you deploy it, check the Windows requirement and the WebView2 dependency for the portable ZIP, use HTTPS or localhost since browser media capture needs a secure context, confirm whether your deployment needs the self-hosted websocket server that the compose file starts, and read the room password and saved allow rules before you grant remote control to anyone.

Frequently asked questions

What can Weblink do from a browser without installing anything?

The web app supports rooms, private chat, a file library and transfers, camera and microphone through browser device APIs, browser screen capture where supported, recording of one local or remote source, remote control of a compatible desktop host, and browser picture-in-picture. It can also be installed as a PWA where the browser supports it.

Which platforms does the Weblink desktop app support?

The supported desktop target is Windows 10 22H2 or Windows 11 on x64 with WebView2 120 or newer. The Windows x64 installer sets up WebView2 when needed, and the portable ZIP requires WebView2 120 or newer along with its weblink-portable marker beside the executable.

How does Weblink decide who can control a remote computer?

You run the desktop app on the machine you want to reach and request control from another device, and the host either approves the request or uses a previously saved allow rule. A request can start display sharing after approval, while window shares remain view-only.

Can I self host the Weblink websocket server?

Yes, the repository ships a docker-compose file with a weblink service built from the Dockerfile and a ws-server built from servers/weblink-ws-server, published on ports 8080, 443 and 9000, with SSL enabled through the ENABLE_SSL flag and certificates mounted from a local directory.

What licence is Weblink released under?

The project is MIT licensed, with the licence field set to MIT in the root package.json and a LICENSE file in the repository. The homepage is webl.ink and the latest listed release is 1.2.0 from 2026-10-18.

Official sources

  1. 99percentpeople/weblink on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/99percentpeople-weblink.svg)](https://hysenlabs.com/projects/99percentpeople-weblink)

Was this useful?