Skip to content

Development Guide

pinjinx edited this page Aug 4, 2026 · 1 revision

This guide covers everything needed to get Rein running locally, contribute code, and test across platforms.


Prerequisites

Tool Version Notes
Node.js ≥ 18 LTS recommended
npm Bundled with Node
GStreamer 1.20+ Auto-installed by postinstall on macOS/Windows; system package on Linux
Linux: uinput access See Linux-specific setup below
macOS: Accessibility Required for input injection

Quick Start

# 1. Clone
git clone https://github.com/AOSSIE-Org/Rein.git
cd Rein

# 2. Install (also installs/checks GStreamer via postinstall)
npm install

# 3. Run dev server
npm run dev

# 4. Open in browser
open http://localhost:3000/settings

Platform-Specific Setup

Linux

Rein uses /dev/uinput for virtual input devices. Setup is required once:

# Create the uinput group
sudo groupadd -f uinput

# Set device permissions
sudo tee /etc/udev/rules.d/99-rein.rules <<EOF
KERNEL=="uinput", MODE="0660", GROUP="uinput"
EOF

# Add your user to the group
sudo usermod -aG uinput $USER

# Reload rules
sudo udevadm control --reload-rules
sudo udevadm trigger

# Log out and back in, then verify:
ls -l /dev/uinput
# Should show: crw-rw---- 1 root uinput ... /dev/uinput

GStreamer on Linux

Install via your package manager:

# Ubuntu / Debian
sudo apt install gstreamer1.0-tools gstreamer1.0-plugins-base \
  gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
  gstreamer1.0-libav

# Fedora / RHEL
sudo dnf install gstreamer1 gstreamer1-plugins-base gstreamer1-plugins-good \
  gstreamer1-plugins-bad-free gstreamer1-plugins-ugly

# Arch Linux
sudo pacman -S gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly

Wayland (PipeWire + XDG Desktop Portal)

For Wayland sessions, ensure:

systemctl --user status pipewire pipewire-pulse
systemctl --user status xdg-desktop-portal xdg-desktop-portal-gnome  # or -kde, -wlr, etc.

If the portal is not running, start it:

systemctl --user start xdg-desktop-portal

Nix / NixOS

A shell.nix is provided:

nix-shell
npm install
npm run dev

macOS

Grant Accessibility permission to your terminal or IDE:

System Settings → Privacy & Security → Accessibility → Add your terminal

GStreamer is automatically downloaded by npm install (postinstall script).

Windows

GStreamer is automatically downloaded by npm install.

For testing, ensure Windows Defender / antivirus doesn't block the GStreamer executable.


NPM Scripts

Script Command Description
predev biome check . --write Auto-format before dev
dev vite dev --host Start Vite dev server
build vite build Production build → .output/
start vite preview --host --open Preview production build
electron npx electron . Run Electron (requires production build)
electron-dev concurrently ... Run Electron with Vite dev server
dist electron-builder Package Electron app
test vitest run Run all tests
check biome check . Lint & format check
check:fix biome check . --write Auto-fix lint & format

Project Structure

Rein/
├── electron/
│   └── main.cjs              # Electron main process & server process launcher
├── public/
│   └── app_icon/             # Application icons
├── scripts/
│   └── install-gstreamer.js  # GStreamer postinstall resolution script
├── src/
│   ├── components/
│   │   └── Trackpad/         # React Trackpad UI components
│   │       ├── Buffer.tsx
│   │       ├── ControlBar.tsx
│   │       ├── ErrorComponent.tsx
│   │       ├── ExtraKeys.tsx
│   │       ├── ScreenMirror.tsx
│   │       └── TouchArea.tsx
│   ├── contexts/
│   │   ├── ConnectionProvider.tsx  # Dual DataChannel React context & RTT measurement
│   │   └── DebugContext.tsx         # Client log interception & debug context provider
│   ├── hooks/
│   │   ├── useRemoteConnection.ts  # Thin wrapper over ConnectionProvider
│   │   ├── useTrackpadGesture.ts   # Touch gesture state machine & scroll locking
│   │   └── useWebRtcStream.ts      # WebSocket signaling, RTCPeerConnection, freeze watchdog
│   ├── routes/
│   │   ├── __root.tsx         # Root layout + navigation bar
│   │   ├── debug.tsx          # Host telemetry chart, session snapshots, SSE log console
│   │   ├── index.tsx          # Redirect to /settings
│   │   ├── settings.tsx       # Settings UI & QR code generator
│   │   └── trackpad.tsx       # Main remote trackpad control interface
│   ├── server/
│   │   ├── drivers/
│   │   │   ├── keyMap.ts               # Logical key name → native code mapper
│   │   │   ├── utils.ts                # Acceleration curve calculations
│   │   │   ├── linux/                  # /dev/uinput virtual device driver via Koffi FFI
│   │   │   ├── mac/                    # CoreGraphics CGEvent driver
│   │   │   └── windows/                # Win32 SendInput & Synthetic Pointer driver
│   │   ├── gstreamer/
│   │   │   ├── captureProvider.ts      # Platform screen capture source factory
│   │   │   ├── gstManager.ts           # gst-launch-1.0 process manager (x264enc + udpsink)
│   │   │   ├── gstPaths.ts             # GStreamer binary & environment path resolver
│   │   │   └── utils.ts                # Wayland XDG Desktop Portal & D-Bus helpers
│   │   ├── constants.ts                # Server constants (RTP_HOST, RTP_PORT 5004)
│   │   ├── InputHandler.ts             # 8ms throttle, gesture sanitization, driver dispatch
│   │   ├── server.ts                   # HTTP router, API handlers, SseTransport logging
│   │   ├── tokenStore.ts               # Token CRUD, timing-safe compare, tokens.json persistence
│   │   ├── types.ts                    # Shared server-side TypeScript interfaces
│   │   └── webRTC.ts                   # werift WebRTC manager, WebSocket server (/ws), UDP relay
│   ├── utils/
│   │   ├── i18n.ts                     # Key-value internationalization helper
│   │   ├── logger.ts                   # Winston logger instance
│   │   ├── net.ts                      # UDP socket LAN IP detection helper
│   │   └── welcome.ts                  # CLI startup welcome banner
│   ├── config.tsx                      # App UI constants (themes, storage keys)
│   ├── router.tsx                      # TanStack Router setup
│   ├── routeTree.gen.ts                # Auto-generated TanStack route tree
│   ├── server-config.json              # Server configuration file
│   ├── styles.css                      # Global Tailwind CSS styles
│   ├── tokens.json                     # Persisted auth tokens (gitignored)
│   └── types.tsx                       # Global TypeScript types
├── biome.json                          # Biome linter/formatter config
├── package.json
├── postcss.config.js
├── shell.nix                           # Nix development environment
├── tsconfig.json
└── vite.config.ts                      # Vite build config + signaling middleware plugin

Testing

Unit Tests

npm run test

Uses Vitest with jsdom. Test files follow the *.test.ts / *.spec.ts convention.

Manual Testing on a VM

  1. Set VirtualBox network adapter to Bridged Adapter
  2. Select your active Wi-Fi or Ethernet interface
  3. Run npm run dev in the VM
  4. Find the VM's LAN IP: ip addr or hostname -I
  5. Connect your phone to the same Wi-Fi
  6. Navigate to http://<VM_IP>:3000/settings

Testing Without GStreamer

If GStreamer is not available, the pipeline falls back to videotestsrc pattern=ball — an animated ball pattern. This allows testing the WebRTC data channel input path without a real screen capture.


Code Style

Rein uses Biome for linting and formatting:

npm run check        # Check only
npm run check:fix    # Auto-fix

Key style rules:

  • ES6+ syntax, const preferred over let
  • No any types
  • Arrow functions for callbacks
  • No console.log in committed code (use logger.ts)
  • Keep functions small and focused

Contributing

  1. Join the Discord server (Project → Rein) — mandatory
  2. Find or create an issue
  3. Fork the repo and create a feature branch
  4. Make changes, run npm run check:fix and npm run test
  5. Submit a PR with a clear description
  6. Post your PR link in the Discord channel

See CONTRIBUTING.md for the full guide.


Environment Variables

Variable Used By Description
DISPLAY GStreamer (X11) X11 display (default :0)
XAUTHORITY GStreamer (X11) X11 auth cookie path
XDG_SESSION_TYPE CaptureProvider Detect Wayland session
WAYLAND_DISPLAY CaptureProvider Detect Wayland session
GST_PLUGIN_PATH GstManager GStreamer plugin search path
GST_PLUGIN_SCANNER GstManager GStreamer plugin scanner binary
VITE_DEV_SERVER_URL Electron dev URL for Electron to load
HOST Nitro production Server bind address
PORT Nitro production Server port

Clone this wiki locally