Skip to content

feat: Add ODE Desktop Application (Tauri + React)#610

Merged
r0ssing merged 19 commits intoOpenDataEnsemble:devfrom
najuna-brian:feat/add-desktop-app
Apr 16, 2026
Merged

feat: Add ODE Desktop Application (Tauri + React)#610
r0ssing merged 19 commits intoOpenDataEnsemble:devfrom
najuna-brian:feat/add-desktop-app

Conversation

@najuna-brian
Copy link
Copy Markdown
Contributor

Overview

This PR introduces ODE Desktop, a cross-platform desktop application built with Tauri, React, and Rust. The desktop app provides two core modes to enable field staff and form developers:

  1. Data Management: Pull, inspect, correct, and sync observations with import/export and conflict resolution capabilities
  2. Forms & App Workbench: Develop and test app bundles, embedded formplayer, and custom apps with behavior parity to mobile

Architecture

graph TB
    User["👤 User<br/>(Field Staff / Form Developer)"]
    Desktop["🖥️ ODE Desktop<br/>(Tauri App)"]
    React["⚛️ React Frontend<br/>(Vite)"]
    Rust["🦀 Rust Backend<br/>(Tauri Commands)"]
    Synk["🔗 Synkronus API<br/>(OpenAPI Client)"]
    Formplayer["📋 Embedded Formplayer<br/>(React Native Web)"]
    
    User -->|Interacts with| Desktop
    Desktop --> React
    Desktop --> Rust
    React -->|HTTP/OpenAPI| Synk
    React -->|Loads in WebView| Formplayer
    Formplayer -->|Bridge Contract| React
    Rust -->|OS Integration| OS["🔧 OS APIs<br/>(File, Dialog, etc)"]
Loading

Key Features

Feature Purpose Status
Data Management Hub Pull, inspect and correct observations; manage sync state and conflicts ✅ MVP
Forms & App Workbench Test app bundles and custom apps before mobile deployment ✅ MVP
Embedded Formplayer Run the full formplayer runtime within the desktop app ✅ Integrated
OpenAPI Client Automatic TypeScript client generation from Synkronus OpenAPI spec ✅ Codegen
Cross-Platform Build Automatic builds for Windows (.msi), macOS (.dmg), Linux (deb/AppImage) ✅ Ready
Development Tools ESLint, Prettier, Vitest, TypeScript strict mode ✅ Configured

Technical Stack

Layer Technology Version Purpose
Desktop Framework Tauri v2 Native app shell + window management
Frontend Framework React ^18.3.1 UI components and state management
Bundler Vite ^6.0.3 High-speed dev server and production builds
Backend/Rust Cargo - System integration and desktop APIs
State Management Zustand ^5.0.8 Lightweight global state
Routing React Router ^7.8.2 Multi-screen navigation
API Client OpenAPI Generator auto-generated Type-safe Synkronus API calls
Testing Vitest ^3.2.4 Unit and component testing
Linting ESLint ^9.39.2 Code quality
Formatting Prettier ^3.8.1 Code consistency

Project Structure

desktop/
├── src/
│   ├── App.tsx                          # Root component
│   ├── components/                      # Reusable UI components
│   │   ├── FormplayerEmbed.tsx         # Embedded formplayer container
│   │   ├── CustomAppEmbed.tsx          # Custom app bundling host
│   │   └── FormFinalizeDialog.tsx      # Form submission dialog
│   ├── lib/                            # Utility libraries
│   │   ├── formplayerHost.ts           # Formplayer WebView bridge
│   │   ├── formPreviewBridge.ts        # Form preview bridge
│   │   └── bundleResolution.ts         # App bundle extension merging
│   ├── generated/                      # Auto-generated code
│   │   └── synkronus-client/          # OpenAPI client (do not edit)
│   └── App.test.tsx                   # Component tests
├── src-tauri/                          # Rust/Tauri backend
│   ├── src/                           # Rust source
│   ├── Cargo.toml                     # Rust dependencies
│   ├── capabilities/                  # Tauri permissions
│   └── icons/                         # App icons
├── public/
│   ├── formulus-injection.js          # Formplayer bridge injection
│   ├── formplayer-host-stub.js        # Formplayer host stub
│   └── formplayer_dist/               # Built formplayer bundle (auto-copied)
├── package.json                        # Dependencies & scripts
├── tsconfig.json                       # TypeScript config
├── eslint.config.js                    # Linting rules
├── prettier.config.js                  # Formatting config
├── tauri.conf.json                     # Tauri config (CSP, icons, etc)
└── vitest.config.ts                    # Test configuration

Build & Deployment

Development

# Install and start dev server
cd desktop
pnpm install
pnpm dev

# In another terminal, start Tauri dev server
pnpm tauri dev

Production Build

# Build desktop app for current platform
pnpm tauri build
# Outputs: .msi (Windows), .dmg/.app (macOS), .AppImage/.deb (Linux)

CI/CD Integration

Workflow Trigger Output
ode-desktop feat/add-desktop-app push Desktop bundles + validation
Type Check Each commit TypeScript compilation check
Linting Each commit ESLint compliance
Tests Each commit Vitest suite execution

See .github/CICD.md for workflow details.

Dependency Management

Frontend Dependencies (React + UI)

  • react / react-dom: UI framework
  • react-router-dom: Client-side routing
  • zustand: Minimal state management
  • @tauri-apps/api: Tauri IPC & plugins
  • @tauri-apps/plugin-dialog: File/folder dialogs
  • @tauri-apps/plugin-opener: Open external links

DevDependencies

  • vite / @vitejs/plugin-react: Build tooling
  • typescript / typescript-eslint: Type safety & linting
  • eslint / prettier: Code quality
  • vitest / @testing-library/*: Testing
  • @openapitools/openapi-generator-cli: OpenAPI codegen

API Integration

OpenAPI Client Generation

The desktop app auto-generates a TypeScript client from the Synkronus OpenAPI specification:

# Regenerate client from OpenAPI spec
pnpm codegen:synk-client

# Configuration: openapi.client.config.json
# Spec location:  ../synkronus/openapi/synkronus.yaml
# Output:         src/generated/synkronus-client/

CI/CD: The ode-desktop workflow regenerates the client and fails the build if the repo is out of sync with the spec.

Component Integration

Formplayer Embedding

The desktop app embeds the built Formplayer from formulus-formplayer/:

  1. Build formplayerformulus-formplayer/build/
  2. Copy to desktopdesktop/public/formplayer_dist/
  3. Load in WebView<iframe src="formplayer_dist/index.html">

Build chain:

pnpm build:formplayer    # Build formulus-formplayer and copy
pnpm build:tauri         # Entire desktop app build
pnpm tauri build         # Full desktop bundle (includes formplayer)

Bridge Contract

The Formulus Interface Definition is the source of truth for formulusAPI and postMessage communication:

  • Location: formulus/src/webview/FormulusInterfaceDefinition.ts
  • After changes: Regenerate in formulus-formplayer via sync-interface

Testing

Unit & Component Tests

pnpm test              # Run all tests once
pnpm test:watch       # Watch mode
pnpm test:ui          # UI test explorer

Test files co-located with source (e.g., App.test.tsx next to App.tsx).

Code Quality

pnpm lint              # Check linting
pnpm lint:fix          # Auto-fix
pnpm format:check      # Check formatting
pnpm format            # Auto-format
pnpm typecheck         # TypeScript strict check

Browser & System Requirements

Windows

  • WebView2 runtime (usually present on Windows 10/11)
  • .NET 7+ (included with WebView2)

macOS

  • Xcode command-line tools
  • macOS 10.13+ (for app execution)

Linux

Changes Summary

Category Metric Details
Files Added +264 Desktop app (frontend + Rust), CI/CD, docs
Lines Added +38,933 Mostly transpiled/generated code & dependencies
Lines Removed -1,096 Documentation cleanup
Key Directories desktop/ 2000+ files including node_modules (locked)
CI/CD .github/workflows/ New ode-desktop.yml workflow

Changed Packages

  • formulus: Updated app bridge and WebView integration
  • formulus-formplayer: New build:ode-desktop script for desktop builds
  • docs: ROADMAP updates reflecting desktop milestone

Security & Content Security Policy (CSP)

Updated tauri.conf.json CSP directives:

  • frame-src 'self': Allow same-origin iframes (embedded formplayer)
  • child-src 'self': Allow child content from trusted sources

Tauri Security documentation.

Deployment & Distribution

Official Releases

Published builds are attached to GitHub Releases with platform-specific artifacts:

  • Windows: .msi installer
  • macOS: .dmg / .app bundle
  • Linux: .AppImage / .deb packages

Development Builds

For early testing or internal distribution:

pnpm tauri build

# Platform-specific output location:
# - macOS: src-tauri/target/release/bundle/dmg/
# - Windows: src-tauri/target/release/bundle/msi/
# - Linux: src-tauri/target/release/bundle/deb/ (and appimage)

Installation Script

A placeholder installer is provided at scripts/install-ode-desktop.sh (to be wired to real release asset URLs).

Breaking Changes

None — Backward compatible with existing:

  • Formulus web app
  • Formulus mobile (React Native)
  • Synkronus API contract
  • Portal UI and CLI

Desktop is an additive feature; no public APIs were modified.

Future Enhancements

  • Offline-first sync with conflict resolution UI
  • Form bundle preview with hot reload
  • Custom app debugger with DevTools integration
  • Settings panel (API endpoint, auth, logging)
  • Installer auto-updates via Tauri updater plugin

Review Checklist

  • Build passes: pnpm build:tauri and pnpm tauri build
  • Linting passes: pnpm lint
  • Tests pass: pnpm test
  • TS strict: pnpm typecheck
  • OpenAPI client synced: pnpm codegen:synk-client
  • Formplayer embedded: pnpm build:formplayer && pnpm tauri build
  • Desktop app launches: pnpm tauri dev

Related Issues & PRs

  • Relates to ODE roadmap milestone: Desktop Data Management & Workbench
  • Depends on: Synkronus OpenAPI schema (synced via codegen)
  • Feeds into: Mobile parity (shared bridge contract)

Contributors

Built with ❤️ by the ODE team.


Getting Started (For Reviewers)

Quick Test

# Build and run desktop app
cd desktop
pnpm install
pnpm tauri dev

# In another terminal, build formplayer
cd ../formulus-formplayer
npm run build:ode-desktop

Test Scenarios

  1. Data Management Mode: Navigate to sync, pull observations
  2. Forms Workbench Mode: Load an app bundle, preview a form
  3. Cross-platform: Test on Windows, macOS, or Linux (if available)

Questions?

  • Architecture: See desktop/README.md (Architecture Pointers section)
  • Development: See desktop/README.md (Development section)
  • API Integration: See desktop/README.md (OpenAPI Client section)

Merge strategy: Squash and merge to dev (or rebase if keeping commit history).

@najuna-brian najuna-brian requested a review from r0ssing April 16, 2026 10:20
Copy link
Copy Markdown
Contributor

@r0ssing r0ssing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @najuna-brian ! This will be a great addition to our data ensemble 😄

@r0ssing r0ssing merged commit b7dbf41 into OpenDataEnsemble:dev Apr 16, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants