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."
Isn't there a way to control module name resolution when compiling a react-native app? On the browser side we have JSPM and Webpack, which let you alias module names so you don't have to rewrite third party code.
It's pretty useful too if you have a drop-in replacement for another library. Heck with JSPM, you can even scope module resolution per module... so you can say module A should resolve to B but only within the context of an import from module C, everything else gets the normal resolution.
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!
Hi all! Thanks for the post! Here are some links to help you check out Exponent and get any idea what it can do -- all you need to do is download the Exponent client from the app / play store and you can open any of these:
- A pre-launch version of "React Native Playground" in Exponent: https://getexponent.com/@rnplay/rnplay (just sign in as a guest and go to the Explore tab)
I'm interested in the game example. How is that built exactly? Is the game built in React Native (I presume not) or is React Native just used for UI elements? If so, what is the game built with?
The game runs on Exponent and uses React Native for rendering (as all Exponent apps do). It uses individual `Image` components for each sprite. This gets choppy when you have a lot of sprites so we're experimenting with more performant ways of rendering for games.
I've ran through most of the intro doc, but I'm still not sure if Exponent supports invoking platform/system APIs? E.g. if I want to access clipboard contents, or wifi network configuration, etc, how can it be done with Exponent? With React Native, I can write corresponding functionalities using Java or Swift/ObjC, and then integrate it with the RN main app, but how can this be done with Exponent?
For now, Exponent just lets you write things that only use JS, and we make that easy and reliable and straightforward. We actually think this is the best way to write most apps that can be built this way since the code is easier to maintain and works cross platform, and you can do things like instant updates much more reliably when all your code is JS.
We're looking at a way you can write Java/Swift/Obj-C extensions for Exponent, but that will take us some time.
With Exponent you write just JavaScript. In addition to most of the APIs that come with React Native, Exponent provides several APIs (https://docs.getexponent.com/versions/latest/sdk/index.html) and we're steadily adding more. If there's a native API we don't have yet that developers need, they tell us about it and we add it to our roadmap.
Exponent is open-source, too, so if you needed to you could fork it and write your own native code or make a raw React Native app. We recommend writing pure JS apps if you can, though. At Exponent we write native code so other people don't have to.
Check out re-natal [0] if you are interested in using react native with clojurescript. Re-frame (cljs's redux?) and reagent (cljs's react wrapper) are a joy to use and clojurescript with REPL is something I'd pick over plain JS almost any day.
ClojureScript along with re-frame/reagent/etc. can actually be used with Exponent too! "lein new exponent my-project" creates an exponent project, ready with figwheel for live REPL. The template can be found here if you want to just read it online: https://github.com/tiensonqin/exponent-cljs-template
It actually is based on the re-natal code but automatically saves and uses the devserver ip and doesnt need th ios/android native code because it runs in Exponent. Other than that the functionality is the same I think, with the same difference as plain RN vs. Exponent.
This looks cool. But are the builds happening remotely on the Exponent servers, or have I misunderstood that?
Edit - brentvatne just answered this: "we handle builds for you when you want to ship to the app store, before that you can just use the Exponent client".
When you're developing you can use Exponent's apps from the App Store/Play Store, so you can get started immediately and let other people test your app easily. Once you're ready to put your app in the stores you start a build using our CLI and we build it on our servers (see https://docs.getexponent.com/versions/latest/guides/building...). We want to make it easy for people on Windows and Linux to build apps so don't require you to use Xcode or Android Studio. If you don't want the builds to happen on our servers our clients are open source so you can do it yourself if you want (https://github.com/exponentjs/exponent).
It looks really great! Is it possible to take down apps from the Exponent servers once I've published on the App stores or do I have to keep all my code and resources public?
(I saw mentioned on the blog you work on: "making it easier to deploy your app to any server and not depend on ours" as well which will be super cool)
Without support for native modules, is it at all possible to use something like card.io with Exponent? Also, are there any plans to allow plugins that make use of native modules in the way the core SDK uses them?
card.io isn't supported right now, but it's definitely on our list! If you want to use it right now you can send us a PR or just maintain a fork of our clients.
We have some plans to allow custom native modules without forking the client but that's probably a few months out. If you join our slack we'll let you know about any updates: https://slack.exponentjs.com/
Does XDE run on Raspberry Pi? (Or if not, how difficult would it be to port?) It would be a nice hook to introduce people to programming if they could write mobile apps on the Pi.
I think it should? If you had Linux running on it and a monitor and keyboard hooked up, I can't think of any reason why it wouldn't work.
If there are any problems, they would probably be easy to fix. The thing I'd be most worried about is just that some things might run very slow on the Pi.
XDE does run on a Raspberry Pi, this is a photo of it running on my RPi 3: https://i.imgur.com/ZvLtqjR.jpg. You don't need anything special aside from following the instructions on GitHub to run XDE from source.
The RPi hardware is pretty slow for a development machine. I have mine minimally overclocked but the CPU temperature was coming close to 85 °C and it took minutes for the starter project to initially load (after that, the build is cached). On the other hand if all you have is a Raspberry Pi, then Exponent is one of the few ways you can make iPhone apps.
We haven't tried but I think it would since XDE is made with Electron and runs on Linux. You might have to use real devices to run your app, though, since the RPi might not be powerful enough to run the Android emulator well and the iOS simulator is Mac-only. I'll have to try out XDE on my RPi sometime tonight.
Also if you meant automated testing, here's an Exponent app that runs jasmine to test Exponent SDK API end-to-end: https://github.com/exponentjs/test-suite This is useful for testing network requests, API calls, etc. in your app JS.
Exponent apps have URLs, so if you have the URL for an Exponent app, you can just download the Exponent developer app from the iOS App Store / Play Store and then open the URL.
If you have the source code for the app, just open the project directory in XDE (our desktop software) and it will give you a development URL that you can open in the Simulator or on your phone.
In general, testing Exponent apps is way easier than testing apps other ways. We put a lot of time into making it simple.
On the one hand I like this, as it adds in more shared functionality across both iOS and Android out of the box (maps for example). On the other hand, I believe this also breaks the ability to add in custom RN modules, which is part of the reason I enjoy it. Would love to see some of this getting folded back into react native core.
We intentionally chose to not let users drop down to native -- the idea of having an interpreted language that sits on top of a native runtime on multiple platforms is not a new one, and it allows for so many benefits that you lose out on if developers can add arbitrary compiled code with direct access to system APIs.
Additionally, there is a significant value-add of using Exponent in terms of upgrades. As great as React Native is, it also moves extremely fast and it can be difficult to keep up with new releases -- a change in React Native might cause several of your native dependencies to break, and you'll need to fork those libraries and fix them if the maintainer isn't keeping on the same schedule as you. Updates with Exponent are as simple as updating JavaScript, which has much less churn and breaking changes than the native side (the React API itself is very mature, the APIs for specific native components may change).
Another nice advantage of this is that you can work on an iOS app from Windows and Linux, because you don't need to compile your app with Xcode (we handle builds for you when you want to ship to the app store, before that you can just use the Exponent client).
We ship with a bunch of APIs out of the box and are constantly improving them and adding more. We have analytics tools like Amplitude and Segment built in, Maps, Facebook login (working on Google Login), and more: https://docs.getexponent.com/versions/latest/index.html
React Native is still very early, though, and Exponent is just a small team of seven, so we understand that we can't possibly expose every API that developers working with the platform might want. So, we are working on a way for developers to be able to still take advantage of the Exponent toolchain and layer on native code. I've written up our approach in more detail here: https://blog.getexponent.com/answered-on-slack-ejecting-from...
Interesting choice, and thanks for the detailed explanation.
Sounds like at the end of the day it comes down to Exponent being committed to the user never having to build their own app. I can see that being interesting a to a single dev, or a small app or someone new to mobile development, but to be honest I don't think I could justify using Exponent at a company. On any reasonably experienced team of developers, building an app when native components change or distributing it with something like hockeyapp is not very difficult, so I just wouldn't trade the flexibility of being able to do tricky parts directly in native code for not having to build the app.
I'll dive into your architecture more later tonight, but I'm not clear on why Exponent has to handle exposing specific APIs? Couldn't it work in the same way that React Native doesn't expose specific APIs?
One thing we're always working on at Exponent is growing our set of native modules (for context, I work on Exponent). We believe you can build a very large set of apps without needing to write custom native code, and that set grows quickly as more libraries are ported from native to JS when possible and as we add more native modules to Exponent.
Exponent maintains native modules so they continue to work when React Native changes or when Android & iOS change their APIs. In particular, React Native is released every two weeks and we stay on top of the changelog so you don't have to regarding native modules. We also write native code for both platforms in tandem, often by the same engineer, so that we get coherent APIs that cover common features across both platforms and expose platform-specific capabilities neatly. We want Exponent to feel like a coherent project. All of the docs (and code) for Exponent's modules are in one place, and when you download the Exponent app for development you get all of the native modules right off the bat.
As a data point, the Android version of Li.st (https://play.google.com/store/apps/details?id=st.li.listapp) is built on Exponent and was featured by Google in the Play Store. Li.st is currently one of the best examples of how far you can go with Exponent, and React Native for that matter. We're also on Slack (get an invite here: https://slack.getexponent.com) if you want to chat in real time.
The most limiting thing about Exponent is that you can't add in your own native modules. We give you most of the most commonly desired things, but if you need something very custom--like on-the-fly video processing or low level control over the Bluetooth radio to do a firmware update--then Exponent won't work for you and you should just use regular React Native."
Well probably not a small task to support custom modules, and it allows them to get a pretty powerful tool with a nice core set of features out the door relatively quickly. If exponent becomes successful I imagine they'll add support for custom modules.
This looks really nice. I have a question about React Native though. I was under the impression that React Native meant that you could just take your components from your website and build an app out of it. I'v realized that's not the case. What is the benefit of React Native if you can't share the components?
You can share some components, especially more abstract ones. For example, react-redux creates higher-order components that work with both React DOM and React Native. There's also a project called react-native-web that implements React Native's View components using React DOM's primitive components (https://github.com/necolas/react-native-web).
Components aside, you can share your models and data stores, utilities like Immutable.js and lodash, and other environment-agnostic JavaScript. In addition to code, you can share a lot of knowledge like how to write components, structure an app, use npm, and even just write JavaScript.
The benefit is basically that you build native quality components in Javascript, which saves you from needing to learn new programming languages and frameworks for each platform. Also some components are actually reusable, the custom ones built by RN team, others are platform specific.
It's promising.
I wonder how different is it from Appcelerator Titanium ?
I used it 5 years ago and it converts the written JS into real native code. The downside is that if Apple releases a new set of APIs, you have to wait till the editor (Appcelerator) releases the JS bridge to those new APIs.
Some of the biggest differences are:
(1) Exponent is a free open source project, and we don't try to charge developers to use it. (Titanium is open source now but they try to make money by charging people for premium features--which is totally fine, but just different from what we do)
(2) Exponent is based on React Native which is newer and people seem to like better (search Google for blog posts about experiences using React Native and then search Google for blog posts about using Titanium), though I can't actually compare them personally since I don't know that much about the inner workings of Titanium.
(3) You can do instant app updates with Exponent since the JS is run on the device rather than being cross compiled to native code. I don't think you can do this with Titanium (though I may be wrong -- they've added a lot of features since I last checked on it)
I think it would make sense to provide pre-build packages for few popular distros (Ubuntu, CentOS, Arch). There are some tools that make it much easier, i.e. fpm (https://github.com/jordansissel/fpm).
I was following the Pluralsight course but it looks like Exponent had a big upgrade a while back. Are the old binaries used on the course still available somewhere?
One thing that we do that we think is pretty cool is that we figured out a way to include multiple versions of our SDK (and React Native) in a single binary, so stuff you build with old versions will continue to work.
That's awesome. Will this work with your mobile application? I know that's delivered through the app-store so I assume only the latest version is available there?
The apps in the App Store/Play Store support multiple versions of our SDK. The current versions support back through March. Not sure which SDK version the Pluralsight course is targeting. It might be easier to follow our docs here: https://docs.getexponent.com/versions/latest/introduction/in... which will always be up to date.
Ah sorry, misread your comment. The dev tools will run on Windows 10, but the client apps won't. The client apps run on iOS and Android and the dev tools run on macOS, Windows, and Linux.
One of my teammates working on Exponent was experimenting with ClojureScript and got it running, and one of our YC batchmatches wrote their app with ClojureScript and RN. It's still the very early days and I expect compiled-to-JS to get easier to use. Compiled-to-WASM might also be a good option one day.
i would be really excited about writing performant mobile apps in clojurescript! i'll see if i can find working examples on google now that i know people have done it.
Hey! I work on Exponent. Basically, we don't make money right now. Our plan is to eventually help developers make money and take some cut of that. We're open source so you'll never be locked in if we start doing anything you don't agree with. We talk about it a little more at https://docs.getexponent.com/versions/latest/introduction/fa...