Electron
Electron is Chromium, so the Web SDK runs in the renderer unchanged — one codebase for Windows, macOS and Linux desktops. @applooma/rtc-electron adds what a desktop app needs around it: permissions granted in the main process, and a screen and window picker for screen sharing, wired through a preload bridge.
Requirements#
| Minimum | |
|---|---|
| Electron | 30 |
| Node | 18 |
| Platforms | Windows 10+, macOS 11+, Ubuntu 20.04+ |
Installation#
npm install @applooma/rtc-electron
Nothing native to build. The package has three entry points, one per process: @applooma/rtc-electron/main, @applooma/rtc-electron/preload and @applooma/rtc-electron for the renderer, which also re-exports the whole Web SDK.
Main process#
One call, once, before the first window. It grants camera, microphone and screen capture (everything else stays denied), asks macOS for camera and microphone access up front, answers screen-share requests with the source the page chose, and registers the IPC the preload bridge uses.
const { app, BrowserWindow } = require('electron');const path = require('node:path');const { setupAppMain } = require('@applooma/rtc-electron/main');app.whenReady().then(() => {setupAppMain({// Optional: only grant media to your own pagesallowOrigin: (origin) => origin === 'file://' || origin === 'https://app.example.com',});new BrowserWindow({width: 1200,height: 800,webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true },}).loadFile('index.html');});
| Option | Default | |
|---|---|---|
| session | session.defaultSession | The session to configure. |
| permissions | ['media', 'display-capture'] | Granted; everything else is denied. |
| allowOrigin(origin) | every origin | Restrict which pages get them. |
| askMacMediaAccess | true | Ask macOS for camera and microphone at startup. |
| pickSource(sources) | the first screen | For shares started without a choice from the page. |
| loopbackAudio | true | System audio with a screen share, where the OS allows it. |
Preload
require('@applooma/rtc-electron/preload').exposeAppBridge(); // window.applooma
Sandboxed preloads
New windows are sandboxed by default, and a sandboxed preload cannot require packages. Bundle the preload (Vite, webpack, electron-forge do this) or set sandbox: false for that window. Keep contextIsolation: true and nodeIntegration: false either way.
Renderer#
The call itself is the Web SDK. Screen sharing goes through your own picker.
import AppEngine, { listScreenSources, shareScreen, stopScreenShare } from '@applooma/rtc-electron';const engine = AppEngine.create({ appId: 'YOUR_APP_ID' });engine.on('track-subscribed', (track, user) => {const el = track.attach(); // <video> or <audio>el.dataset.uid = user.uid;document.querySelector('#grid').appendChild(el);});// The token comes from YOUR server — see the Quickstart.const { token, wsUrl } = await fetch('https://your.backend/api/rtc-token').then((r) => r.json());await engine.joinChannel(token, wsUrl, { role: 'host', camera: true, microphone: true });engine.attachLocalVideo(document.querySelector('#me'));// Screen share: list screens and windows with thumbnails, let the user chooseconst sources = await listScreenSources({ types: ['screen', 'window'] });renderPicker(sources, async (source) => {await shareScreen(engine, source.id, { withAudio: true });});document.querySelector('#stop').onclick = () => stopScreenShare(engine);
| AppScreenSource field | |
|---|---|
| id | Pass to shareScreen(). |
| name | Screen or window title. |
| type | 'screen' | 'window' |
| thumbnail | PNG data URL, ready for <img src>. |
| appIcon | Application icon for windows, when the OS gives one. |
Desktop details#
- Devices.
AppEngine.listDevices()lists cameras and microphones; pass the chosen id toengine.setDevice('audioinput', id). - Background. A minimised window keeps publishing. Use
powerSaveBlocker.start('prevent-app-suspension')during a call so the OS does not sleep the machine. - System audio. Capturing system audio with a screen share works on Windows; on macOS it needs a virtual device, so the share is video only.
- Tokens. Mint them on your backend. The API secret never ships inside the app.
- Updates. The SDK is inside your bundle; ship SDK updates with your app's normal update channel.
Building for Windows#
This is the supported way to ship AppLooma RTC on Windows today. A native C++ SDK is on the roadmap — see Windows.
Remote diagnostics#
This package wraps the Web SDK engine, so remote diagnostics work here with no extra setup (Web SDK 0.4.6 or later). The engine keeps recent log lines and a stats snapshot in memory (never audio, video, messages or names) and uploads them, scrubbed, after a call with a problem or when support turns collection on. Call engine.uploadDiagnostics('user-report')in the renderer to send them yourself, for example from a "Report a problem" button. Opt out with new AppEngine({ appId, remoteDiagnostics: false }).
What changed#
0.1.2
- README and this page describe remote diagnostics (
uploadDiagnostics,remoteDiagnostics: false). No API changes.
0.1.1
- Requires Web SDK 0.4.7, which adds a cloud proxy over TLS 443 with automatic retry.
0.1.0
- First release.