I know lots of platforms-of-the-month come through HN, and it's hard to filter the signal from the noise...just wanted to add another voice that Exponent is indeed awesome. Built by one of the sharpest (and most humble) teams in the valley.
I suggest NativeScript as an alternative that's very similar in scope but far more mature, definitely not a platform-of-the-month. The latest version is built on top of TypeScript and Angular 2 instead of React Native like Exponent.
I wonder why we don't hear that much about them in HN.
A more apt comparison might be React Native and NativeScript--both are frameworks that bridge native APIs to JavaScript. In contrast, Exponent is a mobile environment of which React Native is one piece.
Before choosing React Native, we deeply investigated bridging native and JavaScript on our own and one of the ways was a NativeScript-like approach. When React Native was announced we looked at the beta and saw that it exhibited many characteristics we believe are important in a next-gen app framework.
We saw that React Native was designed for multicore phones by dividing work across multiple threads, namely application logic (JS), view and text layout (this is significant), and rendering. Other work like image decoding also runs on a separate thread. One reason React Native's multithreading is fantastic is because hardware manufacturers are adding more cores faster than they are improving the performance of those cores, partly because power consumption grows superlinearly with respect to frequency. The React team is also in the early stages of exploring incremental rendering, which may allow us to parallelize React rendering in JS as well as native.
So far we're happy we chose React Native for Exponent. There's a lot of interest and activity around it and it's on the right track in several ways.
> I suggest NativeScript as an alternative that's very similar in scope but far more mature
NativeScript has been around longer than React Native (at least for Android), but going by Github activity (not the greatest metric, but not aware of a better one) React Native[1] is much more active than NativeScript[2].
Some differences between Exponent and NativeScript:
- Exponent supports building iOS and Android apps on macOS, Windows, and Linux. With NativeScript you need a Mac to build iOS apps.
- Exponent also allows you to push updates to published apps, while publishing with NativeScript is identical to publishing regular iOS and Android apps.
I tested out React Native on Android the other day and it was a real disaster. It doesn't compile for all the CPU ABIs (instruction sets) we have, so if you have native libraries for x86 or arm 64 in your app it immediately breaks it completely. You have to remove all your own libraries for unsupported architectures, then modify your build not to include them, then depend on those platform's compatibility features to run React Native's libraries built for older ABIs like arm v7.
Once you get it running despite their poor support for Android CPUs in their native libraries, half the examples and half the dependencies on the web out there crash immediately because they decided you have to import React and Component from "react" instead of "react-native" now. And there's no stack trace at all when it crashes for that error since it crashes before the normal source map functionality that provides them. My company has hundreds of files being used by React Native on iOS, but they are unusable due to this, even hours of search and replace cannot fix it because it is still crashing out, probably due to one of a dozen dependencies. Similarly if you try to use react redux 4 you are screwed, only 3 is supported. Woe be to anyone who upgrades that dependency.
As a Java programmer who is used to compile time errors when something is wrong, React Native where it crashes constantly at runtime due to poor platform decisions like forcing developers to use a different package from earlier versions is a tough pill to swallow.
> if you have native libraries for x86 or arm 64 in your app it immediately breaks it completely
We handle all the native code for you, so you'll never hit this.
> half the examples and half the dependencies on the web out there crash immediately because they decided you have to import React and Component from "react" instead of "react-native" now
We support multiple React Native versions in our client app, so if you target an old version of React Native it'll keep running on that version even when we upgrade.
The redux 3 vs. 4 part is still an issue, but you should only hit it when you're specifically upgrading your app.
> half the dependencies on the web out there crash immediately because they decided you have to import React and Component from "react" instead of "react-native" now.
That resonates for anybody who has done serious work with npm packages over the past few years. It seems like horrific breakage is the norm. Package authors break backwards compatibility for the stupidest "improvements."
People probably don't like constantly reading about how some large SV player pushed its half-assed ideas through to the public despite the pain it causes.
If the wheel you reinvented is square, you might run into someone who doesn't quite buy into your pitch of this being the future of technology.
No idea but I'm really tired of all the negativity on here. Not even the noblest of projects escape, the negativity still finds a way. Every time I open the comments I think "ok, let's see what the HN crowd complains about this time" and I'm seldom surprised.
Yeah. That's a good articulation of some of the problems but that's tough to learn them the hard way. I wrote a comment below talking a bit about how a lot of these problems start to go away with Exponent but I wanted to offer some thoughts if you or your teammates have embarked on the raw React Native route.
One thing I've learned from working with React Native is that you want to stay fairly up to date with the frequent releases. The Exponent team puts a lot of work into upgrading our own dependencies and maintaining the Exponent API that other developers depend on.
Authors of components and other npm packages will update their code to work with the latest version of React Native. It takes energy to stay up to date since you need to read the release notes and breaking changes and sometimes it's helpful to scan the commit history on the release branch. But this way you can use react-redux v4 and other actively developed dependencies.
On the other hand, though, sometimes component authors don't maintain their projects or support one platform but not the other. When dependencies fall out of date there isn't an easy answer. In the past I've fixed the issues myself and sent pull requests. Showing financial support is also another approach; my teammate Brent wrote a post about this: https://blog.getexponent.com/putting-your-money-where-your-p.... The maintenance of open-source libraries isn't unique to React Native but it's perhaps exacerbated by its cross-platform nature and frequent release cycle.
For the issue about CPU ABIs, I believe React Native supports armeabi-v7a and x86 but not arm64-v8a or x64. It would be great to have native arm64 support but so far no one has needed it enough to implement it instead of using ndk.abiFilters. For what it's worth, this works for Exponent and several other companies with apps that use React Native like Facebook.
Exponent mitigates a lot of the problems the OP described partly because it's a coherent, maintained platform that is one of our core competencies and partly because the design of Exponent guides you away from those issues. The Exponent team spends a lot of time working with React Native and several members including myself are also core contributors to React Native so we see many of these issues up close.
With Exponent you generally write your entire app in JavaScript. We've found that you can build quite a large set of comprehensive apps with pure JS and the APIs that Exponent provides (https://docs.getexponent.com/versions/latest/sdk/index.html). We believe that set of apps will quickly grow as Exponent's API grows. Exponent is open-source, though, so if you needed to you could fork it and write your own native code in which case you might need to think about CPU ABIs. But most people developing on Exponent don't need to think about native code or ABIs at all.
We also stay on top of React Native's changelog and make sure our APIs keep working when React Native changes. Some of your other third-party dependencies might fall out-of-date but the Exponent API stays current. Also with Exponent there aren't any Xcode or Android Studio workspaces to keep up-to-date.
Static type systems for JS like Flow are getting better over time and if enough people use it (or contribute type definitions to https://github.com/flowtype/flow-typed) more of these runtime errors will become compile-time ones. Parts of the JS ecosystem do move quickly, though, largely because of the proliferation of npm.
I had an identical experience last month with broken examples and packages, trying to get started with react native. Additionally, it seems many features are ios only.
I've been building React Native apps since the platform was released. Exponent not only makes the process much easier and approachable, it makes it a breeze to share the final app with your clients or people who you want to test externally. The team at Exponent also contributes a ton to the RN ecosystem as core contributors to React Native and open sourcing a lot of awesome RN components. If you're looking at building cross platform mobile apps I highly recommend checking out Exponent!
Exponent is super cool. Super simple to start building an app. I wish I could use it for every RN project I work on. The team is very responsive too. Totally recommend.
I've been using https://www.decosoftware.com/ and like it a lot, but I really like the documentation on the Exponent website.
Part of the allure of writing React Native apps for me is that knowing React would make me a more valuable developer. I'm curious to see how comfortable I feel saying "I know React" after using these IDEs long-term.
Deco is great! We'd love to get Exponent and Deco playing well together, we've discussed it with their team but haven't had the time yet -- it'll happen one day.
Hmm, they say you can buy an Exponent app through the App Store, and then you can push updates to it through them, and they show up the "next time the user opens the app without having to do through the App Store"?
I don't think downloading scripting or native code that changes how an app behaves from outside sources has been allowed on the App Store, so what gives?
A couple of years ago Apple changed the iOS developer terms to say it's OK to download and run JavaScript as long as it's run on the built-in WebKit or JavaScriptCore engine (section 3.3.2 if you're curious). Exponent uses the built-in JavaScriptCore on iOS.
Apple allows updates like this as long as it doesn't substantially change the behaviour of the application. Of course the definition of 'substantially' is, deliberately I think, left open to interpretation. But new features and bug fixes are okay. Swapping out the application entirely and replacing it with another one would not be.
This looks very interesting, but I'd like to know that if I ever did need to fall back to native APIs, I could keep the code I've written using Exponent's APIs still (even if that means I couldn't use the convenient build tools anymore). Is this possible?
- Fork the Exponent client and add your native API.
- Try to get a patch into upstream.
- If it's not urgent, ask us if we plan to implement it and if it seems like a common enough use case we would add it to our roadmap.
- Go into the Exponent source and copy whatever native code you need into a new React Native project.
We're also working on a way to "eject" from Exponent similar to the create-react-app eject command but easier to reverse and to keep receiving updates to Exponent, because it's not an "all-in" kind of eject, you can read more about that here: https://blog.getexponent.com/answered-on-slack-ejecting-from... (caveat: this feature is still in early development)
Yup! Since our client code is open source, you could run a custom fork of our client that includes the native module(s) you want and still use the JavaScript app code you've written with it. If you end up making such a change let us know and through a pull request or such we could try getting it into standard Exponent!
I wonder why we don't hear that much about them in HN.
https://www.nativescript.org/
Before choosing React Native, we deeply investigated bridging native and JavaScript on our own and one of the ways was a NativeScript-like approach. When React Native was announced we looked at the beta and saw that it exhibited many characteristics we believe are important in a next-gen app framework.
We saw that React Native was designed for multicore phones by dividing work across multiple threads, namely application logic (JS), view and text layout (this is significant), and rendering. Other work like image decoding also runs on a separate thread. One reason React Native's multithreading is fantastic is because hardware manufacturers are adding more cores faster than they are improving the performance of those cores, partly because power consumption grows superlinearly with respect to frequency. The React team is also in the early stages of exploring incremental rendering, which may allow us to parallelize React rendering in JS as well as native.
So far we're happy we chose React Native for Exponent. There's a lot of interest and activity around it and it's on the right track in several ways.
NativeScript has been around longer than React Native (at least for Android), but going by Github activity (not the greatest metric, but not aware of a better one) React Native[1] is much more active than NativeScript[2].
Some differences between Exponent and NativeScript:
- Exponent supports building iOS and Android apps on macOS, Windows, and Linux. With NativeScript you need a Mac to build iOS apps.
- Exponent also allows you to push updates to published apps, while publishing with NativeScript is identical to publishing regular iOS and Android apps.
[1] https://github.com/facebook/react-native [2] https://github.com/NativeScript/NativeScript
Once you get it running despite their poor support for Android CPUs in their native libraries, half the examples and half the dependencies on the web out there crash immediately because they decided you have to import React and Component from "react" instead of "react-native" now. And there's no stack trace at all when it crashes for that error since it crashes before the normal source map functionality that provides them. My company has hundreds of files being used by React Native on iOS, but they are unusable due to this, even hours of search and replace cannot fix it because it is still crashing out, probably due to one of a dozen dependencies. Similarly if you try to use react redux 4 you are screwed, only 3 is supported. Woe be to anyone who upgrades that dependency.
As a Java programmer who is used to compile time errors when something is wrong, React Native where it crashes constantly at runtime due to poor platform decisions like forcing developers to use a different package from earlier versions is a tough pill to swallow.
> if you have native libraries for x86 or arm 64 in your app it immediately breaks it completely
We handle all the native code for you, so you'll never hit this.
> half the examples and half the dependencies on the web out there crash immediately because they decided you have to import React and Component from "react" instead of "react-native" now
We support multiple React Native versions in our client app, so if you target an old version of React Native it'll keep running on that version even when we upgrade.
The redux 3 vs. 4 part is still an issue, but you should only hit it when you're specifically upgrading your app.
How do you handle that exactly?
> half the dependencies on the web out there crash immediately because they decided you have to import React and Component from "react" instead of "react-native" now.
That resonates for anybody who has done serious work with npm packages over the past few years. It seems like horrific breakage is the norm. Package authors break backwards compatibility for the stupidest "improvements."
If the wheel you reinvented is square, you might run into someone who doesn't quite buy into your pitch of this being the future of technology.
As an Android dev, RN is a real head scratcher for me.
I embraced kotlin but I really struggle to find RN's purpose.
Deleted Comment
One thing I've learned from working with React Native is that you want to stay fairly up to date with the frequent releases. The Exponent team puts a lot of work into upgrading our own dependencies and maintaining the Exponent API that other developers depend on.
Authors of components and other npm packages will update their code to work with the latest version of React Native. It takes energy to stay up to date since you need to read the release notes and breaking changes and sometimes it's helpful to scan the commit history on the release branch. But this way you can use react-redux v4 and other actively developed dependencies.
On the other hand, though, sometimes component authors don't maintain their projects or support one platform but not the other. When dependencies fall out of date there isn't an easy answer. In the past I've fixed the issues myself and sent pull requests. Showing financial support is also another approach; my teammate Brent wrote a post about this: https://blog.getexponent.com/putting-your-money-where-your-p.... The maintenance of open-source libraries isn't unique to React Native but it's perhaps exacerbated by its cross-platform nature and frequent release cycle.
For the issue about CPU ABIs, I believe React Native supports armeabi-v7a and x86 but not arm64-v8a or x64. It would be great to have native arm64 support but so far no one has needed it enough to implement it instead of using ndk.abiFilters. For what it's worth, this works for Exponent and several other companies with apps that use React Native like Facebook.
With Exponent you generally write your entire app in JavaScript. We've found that you can build quite a large set of comprehensive apps with pure JS and the APIs that Exponent provides (https://docs.getexponent.com/versions/latest/sdk/index.html). We believe that set of apps will quickly grow as Exponent's API grows. Exponent is open-source, though, so if you needed to you could fork it and write your own native code in which case you might need to think about CPU ABIs. But most people developing on Exponent don't need to think about native code or ABIs at all.
We also stay on top of React Native's changelog and make sure our APIs keep working when React Native changes. Some of your other third-party dependencies might fall out-of-date but the Exponent API stays current. Also with Exponent there aren't any Xcode or Android Studio workspaces to keep up-to-date.
Static type systems for JS like Flow are getting better over time and if enough people use it (or contribute type definitions to https://github.com/flowtype/flow-typed) more of these runtime errors will become compile-time ones. Parts of the JS ecosystem do move quickly, though, largely because of the proliferation of npm.
Deleted Comment
Calling shenanigans given that redux 4 is completely supported and has been supported for a while. Was this many months ago?
I honestly struggle to find the problem addressed by RN, at least if you already know java.
Part of the allure of writing React Native apps for me is that knowing React would make me a more valuable developer. I'm curious to see how comfortable I feel saying "I know React" after using these IDEs long-term.
I don't think downloading scripting or native code that changes how an app behaves from outside sources has been allowed on the App Store, so what gives?
- Fork the Exponent client and add your native API.
- Try to get a patch into upstream.
- If it's not urgent, ask us if we plan to implement it and if it seems like a common enough use case we would add it to our roadmap.
- Go into the Exponent source and copy whatever native code you need into a new React Native project.
We're also working on a way to "eject" from Exponent similar to the create-react-app eject command but easier to reverse and to keep receiving updates to Exponent, because it's not an "all-in" kind of eject, you can read more about that here: https://blog.getexponent.com/answered-on-slack-ejecting-from... (caveat: this feature is still in early development)