2026-03-27 17:18:34 +01:00
# iPad Prototype — Tauri v2 iOS Feasibility Report
**Date:** 2026-03-27
2026-03-27 17:31:16 +01:00
**Status:** VERIFIED — App builds, installs, and renders React UI on iPad Pro 13" simulator (iOS 18.3.1)
2026-03-27 17:18:34 +01:00
## Summary
Laputa can be ported to iPad using Tauri v2 iOS (beta) with **minimal code changes ** . The React frontend stays identical. The Rust backend compiles for iOS with conditional compilation to gate desktop-only features (git CLI, menu bar, MCP, Claude CLI). Vault read/write operations work without changes.
2026-03-27 17:31:16 +01:00
**Key result:** `tauri ios build --target aarch64-sim` succeeds. The app launches on iPad simulator and the React UI renders correctly (telemetry consent dialog, welcome screen, all styled correctly).
2026-03-27 17:18:34 +01:00
## What Works
| Feature | Status | Notes |
|---------|--------|-------|
2026-03-27 17:31:16 +01:00
| Rust backend cross-compilation | VERIFIED | Zero errors, zero warnings for `aarch64-apple-ios-sim` |
| Desktop build (no regressions) | VERIFIED | 581 Rust tests pass, 2201 frontend tests pass, CodeScene gates pass |
| Tauri iOS project generation | VERIFIED | `tauri ios init` generates Xcode project successfully |
| Xcode build for simulator | VERIFIED | `tauri ios build --target aarch64-sim` — **BUILD SUCCEEDED ** |
| App launch on iPad simulator | VERIFIED | Installs and launches on iPad Pro 13" (M4), PID assigned |
| React UI in WebView | VERIFIED | Telemetry consent dialog renders with correct styling, fonts, buttons |
2026-03-27 17:18:34 +01:00
| Vault file read/write | Expected to work | Pure filesystem operations, no process spawning |
| AI chat (Anthropic API) | Expected to work | Uses `reqwest` HTTP, no CLI dependency |
| Search | Expected to work | Pure Rust in-memory search |
| Settings persistence | Expected to work | JSON file read/write |
## What Doesn't Work (Yet)
| Feature | Blocker | Recommended Solution |
|---------|---------|---------------------|
| Git operations | No `git` binary on iOS | **Option B (Working Copy) ** for prototype; **Option A (isomorphic-git) ** for production |
| GitHub clone/push/pull | Depends on git CLI | Same as above |
2026-03-29 15:05:56 +02:00
| Claude CLI streaming | No `claude` binary on iOS | Use Anthropic API directly (requires new implementation) |
2026-03-27 17:18:34 +01:00
| MCP server / WS bridge | Spawns Node.js child process | Skip for mobile; explore in-process MCP later |
| macOS menu bar | Desktop-only API | Touch-native navigation (already handled by React) |
| Updater plugin | Desktop-only | Use TestFlight for updates |
| File open dialog | Different on iOS | `tauri-plugin-dialog` supports iOS — needs testing |
## Changes Made
### `src-tauri/src/lib.rs`
- Gated `WsBridgeChild` , `run_startup_tasks` , `spawn_ws_bridge` , `log_startup_result` behind `#[cfg(desktop)]`
- Mobile build skips MCP registration, WS bridge, and vault migrations at startup
- Run event handler gated for desktop (child process cleanup)
### `src-tauri/src/commands.rs`
- Git commands: desktop implementations remain unchanged; mobile stubs return graceful errors or empty results
- GitHub commands: desktop-only; mobile stubs return errors
- Claude CLI commands: desktop-only; mobile stubs return `installed: false`
- MCP commands: desktop-only; mobile stubs return `NotInstalled`
- Menu commands: desktop-only; mobile stub is a no-op
- Vault, frontmatter, search, AI chat, settings: **unchanged ** (work on both platforms)
### `src-tauri/src/lib.rs`
- `pub mod menu` gated behind `#[cfg(desktop)]`
### `src-tauri/capabilities/`
- `default.json` : scoped to desktop platforms (`linux` , `macOS` , `windows` )
- `mobile.json` : new file with iOS/Android permissions (core, dialog)
### `src-tauri/gen/apple/`
- Full Xcode project generated by `tauri ios init`
- iPad support: all orientations enabled, arm64 architecture
## Architecture: How Mobile Stubs Work
```
Frontend (React) ──invoke──> Tauri Commands ──> Rust Backend
│
┌──────────┴──────────┐
#[cfg(desktop)] #[cfg(mobile)]
│ │
Real impl Stub (error/empty)
(git CLI, (graceful degradation)
menu, MCP)
```
The frontend code doesn't change at all. Commands that aren't available on mobile return errors that the UI can handle gracefully (e.g., hiding the git sync panel, disabling commit buttons).
## Git Strategy for iPad
### Phase 1: Working Copy (Recommended for prototype)
- User manages vault with [Working Copy ](https://workingcopy.app/ ) (git client for iPad)
- Laputa opens the vault via iOS Files API / FileProvider
- Zero git code needed in Laputa — Working Copy handles sync
- **Pro:** Works immediately, robust git implementation
- **Con:** Requires separate app, split UX for sync
### Phase 2: isomorphic-git (Production)
- Pure JS git implementation running in the WebView
- Replace `invoke("git_commit")` etc. with JS-side git operations
- **Pro:** Integrated UX, no external dependency
- **Con:** Slower on large vaults (~9200 files), limited advanced git features
### Phase 3: git2-rs / gitoxide (Future)
- Pure Rust git library compiled into the Tauri binary
- Best performance, no JS bridge overhead
- **Con:** Larger binary size, more integration work
## Next Steps
1. **Install iOS simulator runtime ** — `xcodebuild -downloadPlatform iOS` (downloading ~7GB)
2. **Full Xcode build ** — `npx tauri ios build --target aarch64-sim`
3. **Launch on iPad simulator ** — `npx tauri ios dev`
4. **Test vault read/write ** — open a vault, read/edit a note
5. **Test AI chat ** — verify Anthropic API calls work from iOS WebView
6. **Evaluate touch UX ** — identify layout issues on iPad screen size
7. **File Provider integration ** — test opening vaults from Working Copy via iOS Files
## Prerequisites Installed
- Rust iOS targets: `aarch64-apple-ios` , `aarch64-apple-ios-sim` , `x86_64-apple-ios`
- Xcode 16.2 with iOS 18.3.1 simulator runtime (downloading)
- CocoaPods 1.16.2, xcodegen 2.45.3, libimobiledevice 1.4.0
- Tauri CLI 2.10.0 with iOS support