TronBrowser mobile companion app (iOS + Android) — Expo / React Native,
Expo SDK 57. See docs/mobile-architecture.md
for how this fits the three mobile tracks.
Build prerequisites and the EAS access checklist are documented in
BUILD_READINESS.md.
This is the companion app, not the engine. It uses the system WebView (WKWebView on iOS — mandatory; system WebView on Android), so it is not the Ungoogled Chromium engine and has no Chrome extensions / no bundled Tor. The real engine + Tor ship via the desktop/Linux-phone build and the native Android build — again, see the architecture doc.
cd apps/mobile
pnpm start # Expo dev server (then press i / a)
pnpm ios # native iOS run (needs Xcode)
pnpm android # native Android run (needs Android SDK)
pnpm export # bundle JS for all platforms (CI build proof)
pnpm typecheck # tsc --noEmitBundle ids: dev.tronbrowser.app (iOS + Android).
Implemented screens (tabbed shell, App.tsx). Every tab stays mounted across
switches — WebView history/scroll, chat messages, and drafts survive — while
inactive tabs are hidden from touch and accessibility. Safe areas come from
react-native-safe-area-context (Android 15/16 edge-to-edge), not React
Native's deprecated iOS-only SafeAreaView.
- Browse — in-app browser via
react-native-webview(system engine), URL/search bar with a DuckDuckGo default that needs no account (the desktop correction), back/forward/reload. Android hardware Back walks page history only while this tab is active;window.open/target="_blank"opens in the same tab after HTTP(S) validation; third-party cookies are blocked on Android (on iOS the WKWebView cookie policy belongs to WebKit). - Chat — AI chat UI; the provider seam is
src/lib/ai.ts(setEXPO_PUBLIC_AI_ENDPOINT, else offline echo). - Agents — agent dashboard (sample data → wire
@tronbrowser/agent-runtime). - Settings — sync/privacy/about + Tor status note.
Still to wire (PRD §Mobile): real model provider, sync backend, voice, push notifications.
pnpm test runs the URL/search unit tests plus component tests that render
the real App/screens with only the native boundary mocked (test/mocks/*,
aliased in vitest.config.ts): tab-state preservation, hardware-Back policy,
safe-area insets, window.open handling, and platform cookie wording.
Linked to the EAS project profullstack/tronbrowserdev
(projectId d8bd3b92-f0e1-492e-bf3f-b972d7afec4f, see app.json → extra.eas).
Profiles are in eas.json.
eas build --platform android --profile preview
eas build --platform ios --profile production
eas submit --platform androidMonorepo note: in the EAS GitHub integration
(expo.dev → project → GitHub), set the Base directory to apps/mobile for
both Android and iOS — that's where this Expo app lives.
The address field keeps edits during redirects. Leaving the field without submitting restores the current page address; submitting navigates or reloads without remounting the WebView. Stop cancels the current load. Network failures have a manual Retry action; certificate errors are never bypassed. Explicit recovery from a failed page recreates the WebView so an iOS provisional failure cannot reload the wrong document; this recovery discards native history. After 30 seconds, a dismissible notice flags a slow load without stopping it or covering usable content. Stop remains available; there is no automatic retry.
Component tests drive the native WebView boundary for edit/redirect races, same-source submission, error recovery, cancellation and stale completion events. They do not run Android WebView or iOS WKWebView. Before a native release, verify these flows on the target engine, including two requests to the same URL: native events do not expose a request ID, so URL-based stale-event filtering cannot distinguish every same-URL overlapping navigation. No paid build is required by the local component test suite.