Skip to content

Mobile: run JSS on Android via React Native + nodejs-mobile (PoC + portability findings) #522

@melvincarvalho

Description

@melvincarvalho

What this is

A working proof-of-concept that runs JSS natively on Android as an installable app: a React Native shell embeds a full Node.js runtime (nodejs-mobile) and boots JSS in-process via createServer(). The pod serves on http://localhost:<port>/, the IdP initializes, a single-user pod is created, and a starter app bundle (pilot/profile/home) is auto-installed on first run.

App repo: js-pod/android. This issue collects the findings relevant to JSS itself and tracks the path forward.

What works now

  • RN app boots an embedded Node; JSS runs in the same process (no spawn).
  • IdP signing keys generated (RS256 + ES256), single-user pod created, account seeded.
  • Server listening at http://127.0.0.1:5445, reachable from the phone browser.
  • First-run bootstrap fetches solid-apps from jsDelivr onto the pod (same-origin, so no HTTPS→HTTP mixed-content block when signing in).
  • specialUse foreground service keeps the pod alive when the user switches to a browser.

Fixes required, by where they belong

JSS-actionable (split into their own issues)

Runtime contract (dependency-driven; document or guard)

oidc-provider / jose assume modern Node globals that nodejs-mobile doesn't provide. We polyfill them in the app entry point, but JSS could document a minimum-runtime contract:

  • global Intl.ListFormat (oidc-provider) — absent without ICU.
  • global crypto / Web Crypto (jose key generation) — not auto-attached.
  • URL.parse() static method (oidc-provider) — Node 22.1+.
  • oidc-provider logs "Unsupported runtime. Use Node.js v22.x LTS" — version gate worth noting.

jspod-actionable

  • jspod's start() spawns the jss binary, which can't run in a single-process embedded runtime. An in-process start mode (call createServer directly) would let jspod be embedded too. We bypassed jspod and imported JSS directly.

App/build-level (js-pod/android, not JSS)

RN new-arch + OpenSourceMergedSoMapping; AAPT silently dropping _-prefixed dirs (oidc-provider lib/helpers/_/); assembleRelease to bundle JS; port-shopping when 5444 is taken; specialUse FGS; browser <queries> for Android 11+ package visibility.

Gaps / known issues

  • Pod data lives under the app's extracted nodejs-project dir; lifecycle across app updates needs a deliberate persistent path.
  • Sign-in only works from same-origin apps on the pod (HTTPS web apps hit mixed-content on http://localhost). HTTPS/cert story is open.
  • No external reachability (LAN/remote) yet — localhost-only.
  • The Node-side compat polyfills are nodejs-mobile-specific; they would carry over to any other nodejs-mobile target.

Future work

  • Native Kotlin + nodejs-mobile-android (no React Native): leaner APK, avoids the RN/Hermes/bundle complexity. Reuses the same Node-side compat layer.
  • iOS via nodejs-mobile (RN iOS target, or native Swift).
  • Persistent, user-visible pod storage + backup.
  • Optionally upstream the runtime polyfills so embedded targets need less glue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions