CrossFly is an open-source (Apache 2.0) framework where you write UI and logic in plain Java and it renders on the GPU via LibGDX/OpenGL, compiling to native binaries for Desktop (Windows, macOS and Linux), Android and iOS — plus a WebGL build that runs in any modern browser — Chrome, Firefox, Safari and others. Pair it with CrossFly Sync for offline-first data.
React Native is Meta's open-source (MIT) framework where you write JavaScript/TypeScript and it renders using each platform's native widgets. Its new architecture (JSI/Fabric/TurboModules) replaced the old bridge. It targets Android and iOS; desktop is community/out-of-tree.
The differences that actually matter
The new architecture fixed real problems. Here's what it didn't — and where CrossFly is structurally simpler.
The UI still rides one JavaScript thread
The new architecture (JSI/Fabric) removed the old serialization bridge — a genuine win. What it didn't remove is that your JS logic runs on a single thread. Heavy computation, big lists or complex animations can still starve the UI thread and drop frames; the ecosystem's own answer, FlashList, exists precisely because lists jank on mid-range Android.
CrossFly has no JS thread in the render path at all. The UI is drawn on the GPU from Java, so the whole class of “the JS thread is busy so the screen stutters” problems simply doesn't exist.
Native modules are a compatibility matrix
Anything the core doesn't cover — camera, maps, Bluetooth, payments — is a community native module. Keeping dozens of them mutually compatible across Gradle, CocoaPods and each React Native release is, in the community's own words, close to a full-time job; a version bump is rarely “just bump the number.”
CrossFly owns its render stack and taps the JVM's mature libraries. There's no per-platform native-module zoo to reconcile, and no CocoaPods/Gradle native breakage every time you move a version.
Upgrades have a reputation
React Native is famous for painful upgrades: breaking changes span JS and native, AppDelegate/Gradle tweaks can blank-screen your app, and there's an official Upgrade Helper because diffing versions by hand is that involved. Fall a year behind and you face manual migrations — and the new architecture is now mandatory, so unmigrated modules force your timeline.
One language, one toolchain, a small dependency surface and the JVM's backward-compatibility culture make CrossFly upgrades far more boring — which is exactly what you want from an upgrade.
Desktop is a bolt-on, not a target
React Native's desktop lives in separate, community/Microsoft-maintained repos (react-native-windows/macOS) on their own cadence, lagging core and the new architecture. It's viable, but it's second-class next to iOS and Android.
Desktop is a first-class CrossFly target from the same GPU renderer as mobile — one codebase, one owner, one behaviour across Windows, macOS, Linux, Android, iOS and the browser.
Where CrossFly pulls ahead
Where React Native is genuinely strong
CrossFly vs React Native at a glance
| Dimension | CrossFly | React Native |
|---|---|---|
| Language | Java | JavaScript / TypeScript |
| Rendering | GPU via LibGDX/OpenGL | Native platform widgets |
| Render-path threading | GPU, no JS thread | Single JS thread orchestrates UI |
| Native modules | Few (JVM libraries) | Many community modules to reconcile |
| Java/backend reuse | Direct (it's Java) | Via native modules / JS |
| Platforms | Desktop (Windows, macOS, Linux), Android, iOS, web (any browser) — all first-class | Android, iOS; desktop out-of-tree |
| Offline-first | CrossFly Sync (bidirectional) | Third-party packages |
| Upgrades | Small surface, JVM cadence | Notoriously involved (Upgrade Helper) |
| Governance | Multi-vendor OpenJDK | Meta-led + community |
| License | Open source (Apache 2.0, Core) | Open source (MIT) |