ViewPane
In DevelopmentiOS + Android Companion App
A polished native mobile app — direct-connect, zero cloud, zero data collection, encrypted credential storage, and a fully self-hostable push pipeline. Built to feel like a first-party app, not a third-party afterthought.
About
ViewPane is a production-grade iOS and Android app, built end-to-end on React Native + Expo. The bar was an app-store-quality experience for users who already chose to keep their data on their own hardware: fast, opinionated, and free of the upsell patterns that dominate the consumer mobile-app market.
Existing third-party apps in this space are hobbyist quality, abandoned, or poorly reviewed. ViewPane fills that gap with polish, a privacy posture that holds up to scrutiny, and a push notification stack designed so no vendor cloud ever sits in the alert path.
Architecture
- Direct-connect — App talks directly to the user’s server REST API on their LAN or VPN
- Zero cloud — No CampbellSoft servers in the loop, ever. No account system, no telemetry, no analytics
- Optional self-hosted push relay — A small Node.js + SQLite container the user runs on their own hardware, subscribing to a local MQTT event stream and forwarding alerts so they arrive even when the app is closed. Binds to localhost or VPN by default; never expands a user’s attack surface
- Encrypted credentials — Server URLs, tokens, and passwords stored in iOS Keychain / Android Keystore via expo-secure-store
- Dual-URL auto-failover — Configure both a LAN URL and an external URL (Tailscale, Cloudflare Tunnel, or reverse proxy). The app tries local first, falls back to external automatically when off-network, and switches back when home Wi-Fi reappears — no manual toggling
- Tailscale-first remote access — WireGuard-encrypted end-to-end, no port forwarding required
Features
Live Views
- Multi-server support with one-tap edit
- Static thumbnail grid with manual refresh-all + scheduled auto-refresh
- Live Wall mode — multi-pane grid with configurable polling rate (1–10 fps)
- Fullscreen view with auto-hiding controls
- Connection status indicator shows whether the app is on LAN or External path
Events & Clips
- Filter chips for source, object type, and time range
- Persistent event thumbnails with snapshot + clip playback
- Download-first clip playback — pre-fetches the full mp4 to local cache before play, sidestepping streaming-mp4 truncation issues common with the upstream clip endpoint
- Motion-vs-clip duration shown separately so users know when a clip extends beyond the actual motion event
- Zone display — surfaces which zones an object entered
Recordings Timeline
- Pull continuous footage for any window where the server has recordings
- Quick presets (Last 1 / 5 / 15 min, Last 1 hr) plus custom date + duration
- Files cache briefly during playback, auto-clear on exit
Notifications
- Per-source notification rules synced to the relay so server-side filtering is per-device
- Schedule — Always, Night (10pm–7am), Day (7am–10pm), Custom (user-set 24-hour window with midnight wrap support), or muted via a per-source toggle
- Critical Schedule — independent of the alert schedule, designates when alerts route to a MAX-importance Android channel that overrides Do Not Disturb
- Tap a notification → app opens directly to that event’s detail page
- Relay-side filters: configurable minimum confidence, label blacklist/whitelist, per source+label cooldown, stationary-object filter
Diagnostics
- Server Status screen — per-source FPS, per-detector inference time, service uptime + version, storage usage with progress bars
- Cache management — clear thumbnails, clear video cache (with size readout)
Tech Stack
- React Native + Expo SDK 54 — iOS + Android from one codebase
- TypeScript strict mode throughout
- expo-router — file-based navigation
- expo-secure-store — encrypted credential storage
- expo-notifications + expo-device — push handling, foreground display, deep-link tap routing
- expo-video — native HLS / mp4 playback
- expo-image — efficient snapshot rendering with built-in memory caching
- expo-file-system — download-first video pipeline
- Self-hosted Push Relay (open source, MIT) — Node.js 20 + better-sqlite3 + mqtt.js, ~5MB Docker image, no external dependencies beyond the user’s own stack and Expo’s free Push API
What Makes It Different
Most consumer mobile apps in adjacent categories are built around a vendor cloud that locks users into subscriptions and stores their data on someone else’s servers. ViewPane assumes the opposite — the user already owns their stack, and the app’s job is to be a polished mobile surface for it. No telemetry, no account system, no upsells toward a cloud tier that doesn’t exist, and no third-party SDK ever sees a frame of user data.
The push notification stack in particular is a clean break from how most mobile apps handle background alerts. Instead of routing events through a vendor cloud, ViewPane ships a tiny Docker container the user runs themselves. The relay subscribes to a local MQTT stream and forwards filtered, configurable alerts via Expo’s Push API. The relay code is open and the user’s push tokens never leave their hardware until the actual notification fires.
Privacy
ViewPane collects zero data. No analytics, no telemetry, no crash reporting. All traffic flows directly between the user’s phone and their server. Notification metadata flows through Expo’s Push API on its way to the device — no images, no clips, no location, no account info. Full privacy policy and terms.