HyperStudy Bridge
A unified, high-performance desktop application for bridging HyperStudy web experiments with research hardware devices.
Overview
HyperStudy Bridge provides a reliable, low-latency communication layer between the HyperStudy web application and various research devices. Built with Tauri and Rust for maximum performance and minimal resource usage, it serves as the central hub for all device integrations.
The Bridge runs locally on your research computer and creates a WebSocket server that the HyperStudy web application connects to, enabling real-time communication with connected hardware.
Features
- High Performance: Sub-millisecond latency for time-critical operations
- Multi-Device Support: Simultaneous connection to multiple device types
- Auto-Reconnection: Resilient connection management with automatic recovery
- Real-Time Monitoring: Live status dashboard for all connected devices
- Secure: Local-only connections with sandboxed architecture
- Cross-Platform: macOS, Windows, and Linux
Supported Devices
| Device | Type | Connection | Status |
|---|---|---|---|
| HyperStudy TTL | TTL Pulse Generator | USB Serial | Supported |
| Kernel Flow2 | fNIRS | TCP Socket | Supported |
| Pupil Labs Neon | Eye Tracker | WebSocket | Supported |
| EyeLink 1000 Plus | Eye Tracker | Ethernet (TCP) | Supported* |
| Lab Streaming Layer | Various | LSL Protocol | Supported |
*Requires the SR Research EyeLink Developers Kit installed on the Bridge machine.
Installation
Download the latest release for your platform:
Post-Install Steps
macOS:
- Open the downloaded DMG file and drag HyperStudy Bridge to your Applications folder
- On first launch, if macOS shows a security warning, right-click the app and select "Open"
- The app is signed and notarized by Apple for security
- Grant permissions when prompted:
- Serial Port Access: Required for TTL device communication
- Network Access: Required for device connections
Windows:
- Run the downloaded MSI installer
- Windows may show a SmartScreen warning on first run — click "More info" then "Run anyway"
Linux:
- Make the AppImage executable:
chmod +x HyperStudy-Bridge-*.AppImage - Run the AppImage directly:
./HyperStudy-Bridge-*.AppImage
Configuration
Bridge Settings
Settings are stored in:
- macOS:
~/Library/Application Support/hyperstudy-bridge/ - Windows:
%APPDATA%\hyperstudy-bridge\ - Linux:
~/.config/hyperstudy-bridge/
Example configuration:
{
"bridge": {
"port": 9000,
"autoConnect": true
},
"devices": {
"ttl": {
"port": "/dev/tty.usbmodem1234",
"baudRate": 115200
},
"kernel": {
"ip": "192.168.1.100",
"port": 6767
}
}
}
Device Configuration
Each device type has its own configuration panel in the Bridge GUI:
TTL Device:
- Serial port selection (auto-detected by USB VID/PID)
- Baud rate (default: 115200)
- Pulse duration (default: 10ms, range 1–10000ms)
- Connection timeout settings
Kernel Flow2:
- IP address of Kernel acquisition computer
- Port (default: 6767)
- Event categories to forward
Pupil Labs Neon:
- Connection URL
- Gaze data streaming options
EyeLink 1000 Plus:
- IP address of EyeLink Host PC (default:
100.1.1.1) - Sample rate (250, 500, 1000, or 2000 Hz)
- Display width/height for gaze coordinate mapping
- Requires EyeLink Developers Kit installed separately
LSL Streams:
- Stream name patterns to discover
- Outlet configuration
Usage
Basic Workflow
- Launch the Bridge before starting your experiment
- Configure Devices using the GUI interface
- Connect Devices by clicking "Connect All" or individual device buttons
- Verify Status - all required devices should show green status
- Start Experiment - the Bridge handles all communication automatically
Finding Your Bridge IP Address
Participants need the Bridge's IP address to connect during experiments:
- The Bridge displays its IP address and port in the status bar
- Alternatively, find your IP:
- macOS: Open Terminal and run
ifconfig | grep "inet " - Windows: Open Command Prompt and run
ipconfig - Linux: Run
ip addrorhostname -I
- macOS: Open Terminal and run
WebSocket Protocol
The Bridge exposes a WebSocket server on port 9000 (configurable). Connect using:
const ws = new WebSocket('ws://192.168.1.100:9000');
Message Format:
// Send command to device
{
"type": "command",
"device": "ttl",
"action": "send",
"payload": { "command": "PULSE" }
}
// Receive data from device
{
"type": "data",
"device": "kernel",
"payload": { /* device-specific data */ },
"timestamp": 1634567890123
}
Architecture
┌─────────────────┐ WebSocket ┌──────────────┐
│ HyperStudy │◄──────:9000───────►│ Bridge │
│ Web App │ │ Server │
└─────────────────┘ └──────┬───────┘
│
┌──────────────┬────────────┼────────────┬──────────────┐
│ │ │ │ │
┌─────▼─────┐ ┌─────▼────┐ ┌────▼────┐ ┌─────▼─────┐ ┌─────▼─────┐
│ TTL │ │ EyeLink │ │ Kernel │ │ Pupil │ │ LSL │
│ Serial │ │ FFI │ │ TCP │ │ WS │ │ Streams │
└─────┬─────┘ └─────┬────┘ └────┬────┘ └─────┬─────┘ └─────┬─────┘
│ │ │ │ │
┌─────▼─────┐ ┌────▼─────┐ ┌───▼─────┐ ┌────▼─────┐ ┌─────▼─────┐
│ TTL Device│ │ EyeLink │ │ Flow2 │ │ Neon │ │ LSL-based │
└───────────┘ │ 1000 Plus│ └─────────┘ └──────────┘ │ Devices │
└──────────┘ └───────────┘
Performance
| Metric | Target | Typical |
|---|---|---|
| TTL Latency | <1ms | 0.5ms |
| Message Throughput | >1000/sec | 1500/sec |
| Memory Usage | <100MB | 45MB |
| CPU Usage (idle) | <5% | 2% |
| Startup Time | <2sec | 1.2sec |
Troubleshooting
Connection Issues
Cannot connect from HyperStudy:
- Verify the Bridge is running and shows "Server running on port 9000"
- Check that both devices are on the same network
- Ensure firewall allows connections on port 9000
- Try using the Bridge computer's IP address directly
Port already in use:
# Find process using port 9000
lsof -i :9000
# Kill process if needed (use with caution)
kill -9 <PID>
Device Issues
Serial port access denied (macOS/Linux):
# Add user to dialout group (Linux)
sudo usermod -a -G dialout $USER
# Check port permissions (macOS)
ls -la /dev/tty.*
Device not detected:
- Verify device is powered on and connected
- Check device appears in system (System Information on macOS)
- Try unplugging and reconnecting the device
- Restart the Bridge application
Logging
View Bridge logs for debugging:
- macOS:
~/Library/Logs/hyperstudy-bridge/ - Check the Bridge GUI's log panel for real-time output
Development
For developers who want to build from source:
Prerequisites
Building
# Clone the repository
git clone https://github.com/hyperstudyio/hyperstudy-bridge.git
cd hyperstudy-bridge
# Install dependencies
npm install
# Run in development mode
npm run tauri dev
# Build for production
npm run tauri build
Resources
- GitHub Repository: hyperstudyio/hyperstudy-bridge
- API Documentation: See repository
/docs/api/folder - Related: Kernel Integration Guide
Release Notes
v0.8.25
Released: 2026-03-21
What's Changed
New Features
- In-app auto-updates: The app now checks for updates on launch and can download and install them without leaving the app
- Native menu bar: macOS app menu with About, Check for Updates, Edit (Cmd+C/V/X), and Window submenus; Help menu on Windows/Linux
- Toast notifications: New toast notification system for update status, download progress, and success/error feedback
Technical
- Integrated
tauri-plugin-updaterandtauri-plugin-processfor self-updating and relaunch - Added updater artifact generation (
.tar.gz,.msi.zip,.sig) to all platform build workflows - Added
latest.jsonmanifest generation to release pipeline usingjq - Fixed
tauri.conf.jsonversion discrepancy (was 0.8.4, now synced) - Now tracking
Cargo.lockfor reproducible builds - Updated release process to include
tauri.conf.jsonas third version file
Note: This is the first release with updater support. Future updates will be installable directly from the app. This version must be installed manually.
v0.8.24
Released: 2026-02-25
What's Changed
Bug Fixes
- Fix EyeLink crash when connecting to unreachable Host PC — adds TCP reachability pre-check and FFI timeout to prevent segfault
v0.8.23
Released: 2026-02-25
What's Changed
New Features
- EyeLink 1000 Plus frontend integration — device configuration UI with IP address, sample rate, and display resolution settings
Technical
- Runtime dynamic loading for EyeLink SDK — replaced build-time linking with
libloadingfor runtime SDK detection; one universal binary for all users, EyeLink activates only if the SR Research SDK is present - Removed
eyelinkCargo feature flag — no more separate builds needed; all 15cfgguards removed - Added EyeLink to README supported devices table and CLAUDE.md device specs
- Added frontend tests for EyeLink display fields and IP validation
v0.8.22
Released: 2026-02-25
What's Changed
New Features
- Configurable TTL pulse duration — New "Pulse Duration (ms)" setting in the TTL config modal (1–1000ms, default 10ms). The duration is passed through to both Tauri commands and the WebSocket bridge, and can also be overridden per-pulse via
PULSE <ms>commands.
Bug Fixes
- Fix Neon connect timeout and add connection progress indicator
New Device Support
- Add EyeLink 1000 Plus eye tracker integration
v0.8.21
Released: 2026-02-17
What's Changed
Improvements
- TTL module now sends
PULSE <duration_ms>format to support configurable pulse duration on firmware v1.4.0+ - Configurable
pulse_duration_mssetting (default 10ms, range 1–10000ms) - Serial buffer drain on TTL connect for cleaner handshake
Documentation
- Updated TTL protocol docs, API documentation, and CLAUDE.md for firmware v1.4.0 compatibility
Compatibility
- Requires TTL firmware v1.4.0+ (bridge now sends duration parameter with every PULSE command)
v0.8.20
Released: 2026-02-15
What's Changed
New Features
- Unified FRENZ Connect button — Single "Connect" button now orchestrates the full FRENZ flow: starts the Python bridge, waits for streaming state with a progress bar, then connects LSL streams. "Disconnect" tears down both LSL and the bridge process. No more separate "Start Bridge" / "Stop Bridge" buttons.
Technical
- Backend:
"frenz"recognized in WebSocket device validation; early-return handlers for Connect, Disconnect, and Status actions route throughFrenzLslManager - Frontend: orchestrated multi-step connect with indeterminate progress bar and phase text during bridge startup (30s–3min)
v0.8.19
Released: 2026-02-15
What's Changed
Improvements
- Forward Neon event response data (recording_id, timestamp) to HyperStudy instead of discarding it
- Normalize device IDs to lowercase to prevent silent lookup failures from case mismatches
Bug Fixes
- Fix flaky memory leak integration tests by measuring process RSS instead of system-wide memory
Technical
- Change
Device::send_eventreturn type toResult<serde_json::Value, DeviceError>for richer response data - Upgrade Neon event logging from debug to info level with recording_id
v0.8.18
Released: 2026-02-15
Bug Fixes
- Pupil Labs Neon: Fix "Failed to parse event response" error when sending events without an active recording. The
recording_idfield in the Neon API response is now handled as optional, allowing test events and annotations to succeed regardless of recording state.
v0.8.17
Released: 2026-02-15
What's Changed
Bug Fixes
- Fixed Pupil Labs Neon connection failure — two issues resolved:
- Made
PhoneInfo.portoptional (#[serde(default)]) since the Neon REST API doesn't include it in the Phone status response - Added mDNS hostname pre-resolution for
.localaddresses — the reqwest/hyper HTTP client can't resolve mDNS names on macOS, so we now resolve viatokio::net::lookup_host(which uses the system's mDNSResponder) before making HTTP requests
- Made
v0.8.16
Released: 2026-02-15
What's Changed
Bug Fixes
- Fixed Pupil Labs Neon connection failure caused by missing
portfield in the device's Phone status response. The field is now optional via#[serde(default)], matching the real Neon REST API behavior.
v0.8.15
Released: 2026-02-14
Changes since v0.8.14
🐛 Bug Fixes
- Rewrite Pupil Labs Neon integration to use real REST API (2132975)
🔨 Maintenance
- Bump version to 0.8.15 (5b242ab)
📊 Statistics
- Commits: 2
- Contributors: 1
- Files changed: 17 files changed, 1116 insertions(+), 1204 deletions(-)
Full Changelog: https://github.com/hyperstudyio/hyperstudy-bridge/compare/v0.8.14...v0.8.15
📦 Installation
macOS
- Apple Silicon (M1/M2/M3): Download
HyperStudy-Bridge-v0.8.15-aarch64-apple-darwin.dmg - Intel Macs: Download
HyperStudy-Bridge-v0.8.15-x86_64-apple-darwin.dmg
Open the DMG and drag HyperStudy Bridge to your Applications folder.
All macOS builds are signed and notarized by Apple.
Windows
- Download
HyperStudy-Bridge-v0.8.15-x86_64-windows.msi
Note: Windows may show a SmartScreen warning on first run. Click "More info" → "Run anyway" to proceed.
Linux
- Download
HyperStudy-Bridge-v0.8.15-x86_64-linux.AppImage
Make executable and run: ```bash chmod +x HyperStudy-Bridge-.AppImage ./HyperStudy-Bridge-.AppImage ```
v0.8.14
Released: 2026-02-14
Changes since v0.8.13
✨ Features
- Add PyApp-based FRENZ Python bridge with process lifecycle management (3b1d2b7)
🔨 Maintenance
- Bump version to 0.8.14 (e1d3d41)
- Fix formatting across Rust and frontend code to pass CI checks (4191b2a)
📝 Other Changes
- Fix Kernel event delivery reliability with TCP keepalive and send retry (8446bba)
📊 Statistics
- Commits: 4
- Contributors: 1
- Files changed: 64 files changed, 7959 insertions(+), 2953 deletions(-)
Full Changelog: https://github.com/hyperstudyio/hyperstudy-bridge/compare/v0.8.13...v0.8.14
📦 Installation
macOS
- Apple Silicon (M1/M2/M3): Download
HyperStudy-Bridge-v0.8.14-aarch64-apple-darwin.dmg - Intel Macs: Download
HyperStudy-Bridge-v0.8.14-x86_64-apple-darwin.dmg
Open the DMG and drag HyperStudy Bridge to your Applications folder.
All macOS builds are signed and notarized by Apple.
Windows
- Download
HyperStudy-Bridge-v0.8.14-x86_64-windows.msi
Note: Windows may show a SmartScreen warning on first run. Click "More info" → "Run anyway" to proceed.
Linux
- Download
HyperStudy-Bridge-v0.8.14-x86_64-linux.AppImage
Make executable and run: ```bash chmod +x HyperStudy-Bridge-.AppImage ./HyperStudy-Bridge-.AppImage ```
Release notes are automatically synced from GitHub releases.