It uses a combination of both JS and native code. That JS that RN calls ultimately makes calls out to native Andriod and iOS (and Windows, and macOS) APIs that are compiled to Java and ObjC/Swift (and, I assume, C#?). All of RN's targeted platforms leverage scripting bridges for JS, but only a portion of the actual running code is JS, the part that's native is (usually, but not exclusively) generalized.
It uses a combination of both JS and native code. That JS that RN calls ultimately makes calls out to native Andriod and iOS (and Windows, and macOS) APIs
Exactly like a web browser.
only a portion of the actual running code is JS
“Only a portion” meaning your entire React application! The native parts are the RN framework, any native libraries you’re using, and any native code you’ve added yourself.
What RN brings to the table, as compared to a browser, is a different layout model that’s simpler than the DOM and maps a bit more closely to native widgets.
It also has APIs for sending messages back and forth between JS and native code. That’s also possible with WebViews on all platforms, but RN has a more consistent API (at least on the JS side), so a decent amount of native bindings have been written by third parties.
I think you undervalue just how important this bit is.
It’s so easy to bind your own native code to react-native, it’s quite the game changer for those of us that have been managing two (or more) native code bases for different platforms for the past decade.
I have successfully merged two separate projects for the same iOS/Android app into one by simply writing JS bindings for the existing native code and moving all the business logic to react-native. I probably deleted more LOC than I wrote, and it’s still 90% native code- this is a GPU intensive A/V app.
I’m not a web guy so I can’t compare it to vanilla web react, but for native app development RN has been a huge productivity boost.
> Exactly like a web browser.
>
> “Only a portion” meaning your entire React application! The native parts are the RN framework, any native libraries you’re using, and any native code you’ve added yourself.
Exactly, in the sense that JS is a hosted language in both scenarios, but that's pretty much where the similarities end.
In a web browser, JS is the programmatic interface to behavior after the HTML and CSS are rendered. With React, a function of props that returns a JSX data structure is a declarative-ish interface to additional JS behavior. It's JS all the way down to the renderer.
With RN, JS is an interface to a lower level UI API on the host OS. A function of props that returns a JSX data structure is a declarative-ish interface to a bridge to that API, which performs the actual work.
It's hard to visualize the difference when just thinking of a static output, but easy once you start to think about user events. E.g. there is no `onPress` in the JS bridge for these APIs.
All of React is JS. A substantial portion of React Native, itself, is native. That's the difference.
> What RN brings to the table, as compared to a browser, is a different layout model that’s simpler than the DOM and maps a bit more closely to native widgets.
That's... maybe part of what would attract a dev to RN, but certainly not all of it. It also brings actual (not just close) native UI, with all of the performance and UX expectations that come with that. And it brings the ability to implement performance-critical logic in the native environment while sharing a lot of the rest of your logic with code for other environments.
> It also has APIs for sending messages back and forth between JS and native code. That’s also possible with WebViews on all platforms, but RN has a more consistent API (at least on the JS side), so a decent amount of native bindings have been written by third parties.
If I'm not mistaken, that's how RN works. (I could be mistaken.) In any case... that capability is hardly attractive unless the API is not just consistent internally, but with APIs on other platforms.