React-Native vs native mobile app


#9

It’d be cool to get 1.0 out and then take all lessons learned and do a re-architecture of the app for 2.0.

I agree writing in C (or Nim!) would be interesting to make a portable lib.


#10

Still, this “glue code” requires separate dependency management, build tooling and configuration.

  • CLJS needs re-natal and figwheel
  • Clojure needs lein
  • RN needs react-native tool
  • JS needs npm,
  • Java needs maven or/and gradle and Java
  • ObjC needs cocoapods

where each layer depends on another.

I had build failures absolutely on all levels. Again, we never had developers who understand all of these tools and could resolve problems in a way different from “try another npm version”.

In native development, you have only two separated build pipelines, heavily optimized and well-automated by native tooling – Xcode and Android Studio. It’s an order of magnitude easier from my experience.

Go has nothing to do with status-react build process. It’s consumed as a dependency.

What I meant is that we’ve excluded all the talent that doesn’t speak ClojureScript. The pool of talented RN developers or iOS/Android developers is obviously much bigger. The pool of talents that familiar with JS and can quickly pickup React-Native apps is even bigger (includes the rest of core-team devs, btw) Was CLJS choice worth this massive exclusion? I personally don’t think so.

Exemplary cross-team culture building.


#11

It’s only exclusionary in so far as an individuals comprehension of functional programming.


#12

While I agree that the current stack is far from optimal to attract occasional contributors who might grow into more serious contributors, I must disagree with how hard you make building the app seem, and feel it’s important to balance things with other experiences: even though I had zero experience with React Native, Clojure and very little experience with Node.js when I joined Status, I was able to build, test and contribute (changing a binding) to status-react even before I joined or had access to CCs to ask for directions, by following the instructions in the old wiki. After that, the only time where I had serious issues building status-react was about a month ago, where npm install would hang indefinitely. I was able to solve that by re-cloning the repo, so clearly there was something in the old repo state that was messing up npm (by the way, Igor was able to replace npm with yarn earlier this month, and things are much faster and reliable now). Over time, I (and not only me) learned enough ClojureScript to allow me to add new UI features and some logic independently, so it can definitely be done, but it does require grit. Disclaimer: I don’t build for iOS myself, so I can’t speak for or against how hard it is to build for the platform.

Regarding native stacks, I would definitely agree if we were talking about a strictly mobile-only ecosystem, but I don’t know how you’d be able to do the same for the 5 different platforms we support (iOS, Android, Windows, Linux, MacOS) with similar team size. I guess one approach could be what Plex was doing, have native development for mobile, and web for desktop, but that had its own challenges with lack of logic sharing between platforms (some logic could be very stable in one platform and completely broken in another).

There is a script at scripts/bundle-status-go.sh which you can call and it’ll build your currently checked out status-go into the next builds of status-react, so I can’t really agree that it’s difficult to test out new ideas.


#13

I must disagree with how hard you make building the app seem

Many people were unable to build the project repeatedly. Core developers were unable to build the project repeatedly. The build system was a reason why status-react bounties were excluded from hackathons. What exactly do you disagree with?

The argument “works on my machine” is obviously not the way to handle excessive complexity of the project.

so it can definitely be done

Everything can be done. The question is in costs.

Only? It’s the majority of the talent pool.

So basically it’s the top-down decision to exclude people from Status community because they’re not fans of one particular programming paradigm. If the true motivation was to promote FP, I can totally understand that.


#14

That argument works both ways, and it’s not the argument I’m making. That would equate to saying that it is a matter of chance that the repo can be built. I’ve built it from scratch multiple times from 2 machines, so my point is that I don’t buy that argument. I think the complexity becomes more of a problem in e.g. the time it takes to do a full CI build for a PR than being able to set up the environment in a dev machine but honestly, I haven’t often found myself waiting for a CI build because of that.

That being said, it’s important to continuously improve scripts and documentation to surface/handle known errors and not keep the developer in the dark with cryptic error messages.

Regarding the choice of ClojureScript instead of something like TypeScript, as I mentioned before, I agree that it will easily turn off the occasional contributor, who might be very talented in RN but not willing to put in the time to learn enough ClojureScript to make a contribution he knows it would otherwise take him little time to make.


#15

If we all agree that having competing client implementations is something the Status network can benefit from, I’d like to point out that having a well-defined protocol is only half of the story. The Status-specific ÐApps will define us as a platform and the APIs for creating these ÐApps will impose certain requirements on each implementation.

It’s fair to say that the current extensions API is quite influenced by the best practices of the ClojureScript community. I can see from the current API docs that this is a bit of a misnomer as the intention is to have a data-driven programming model, but we should think about how we can make our platform most welcoming for external developers, while at the same time allowing a rich variety of ÐApps to work across multiple clients.

Let’s discuss what would be a reasonable minimal set of components a conforming client would need:

  • A JavaScript engine - a mostly fine choice since a JavaScript run-time is available on all targeted platforms and it’s the most well-known programming language today. It’s also already required for the browser-based ÐApps.

  • A view engine based on virtual DOM diffing with a limited set of custom components - This gives slight advantage to React-based implementations, but it’s still possible to implement a mini view engine in other toolkits as long as the underlying HTML capabilities are not exposed too much. Please note that allowing extensions to work with arbitrary HTML/CSS is potentially dangerous anyway, due to the possible phishing attacks.

  • A flexible templating engine for the views. Designing React-like views in practice requires support for things like computed attributes, conditions and loops in the view templates. The choice of a templating engine will affect the required footprint of the client and how many developers will be already familiar with it. IMO, the best choice here would be a native JavaScript solution as this would bring only a minimal set of additional dependencies.

If you can trust my expertise as a programming language designer, I’m quite skeptical that the data driven programming model can scale to more complex extensions. The need for a more sophisticated evaluation engine will arrive as soon as things like functions and loops are introduced. The cited benefit of the data driven approach is that it would allow for static analysis to determine the required permissions of each extension, but this is also possible with regular JavaScript if you use a capability system where each capability must be obtained though a well-known API:

var sendMessage = requireCapability("SendMessage")
sendMessage(...)

To make it easier to implement clients and to increase developer inclusivity, I think it’s best if the extensions model is defined directly on top of JavaScript without requiring data formats and custom evaluation engines that won’t be readily available in all programming languages. Another more unorthodox option would be to also expose a WebAssembly run-time powered by the same host API.


#16

Interesting idea! Only this rubs me kind of weird.

Status-specific should not exist. In theory, the extensions are “Status specific” since the dapps in the dapp browser just use an injected web3 and are in no way specific to us, but extensions of some kind exist in almost all messaging clients in the form of hooks or bots or both. I do absolutely agree that it needs to be leaning more towards the exposed API with regular JS (Chrome ext. style) than a specific implementation with more friction like data driven clojure sandbox injection (Slack’s model and curreny Status approach), but I believe it would be difficult to pull off while at the same time successfully preventing people from draining their phones with badly developed extensions. It’s the same reason why mobile browsers don’t allow extensions - script kids (and let’s not fool ourselves into thinking 80% of the JS space isn’t just script kids) will make an infinite loop within a loop within a timeout for anything and that’ll kill your battery right off.

If we had a way to “eWASM-ify” JavaScript by removing some language constructs (i.e. make Status’ JS flavor Turing-incomplete), then it could be pulled off, but I don’t see how that’s doable.

TL;DR: I like the idea of more approachable extension development, but don’t see how we can pull it off without making Status’ battery consumption problem worse. Admittedly, there’s not much preventing bad design in data-based extensions as they are, either.


#17

The reason I call the Status extensions ÐApps is that their execution logic can be distributed across multiple devices and users.

Playing a game of poker with your friends is a Status extension, a very complex distributed system like LibreTaxi can be delivered as an extension as well. Heck, even something like the Slack team onboarding experience can be implemented only as an extension.

So, the extensions are not just about customizing your personal experience in Status, they are about coming up with novel ideas about how to utilize the Status communication protocol and then delivering these ideas as a very well integrated UX. In other words, Status is the platform for real-time communication ÐApps in the Ethereum network.

The battery life problem can be attacked in the same way Ethereum does it. You can give any script a certain time or instruction count budget (essentially gas) and if the script tries to go into an infinite loop, its execution will be terminated. The Web3 pages also feature scripts and they have the same problem - users will rely on things like reputation, ad-blockers and so on to limit their exposure to malicious scripts.


#18

Let’s get back to the topic. I tried to explain that React-Native is not the best solution for the project like Status, if not the worst. But there were only two options (native vs RN), and now there is a third option – Flutter.

Flutter

Flutter is a new Google’s framework for writing mobile apps, and, potentially, desktop- and web-apps too. The promise is similar to RN – write once, run on all platforms, but there is a huge difference: there is no JS/CSS/DOM bullshit. RN was chasing a good idea but has been built on top of the crappiest stack in the history of the software industry, and we all see the result in how many people and millions of dollars we need just to be able to build status-react. Flutter, on the other hand, is a complete rethinking of how apps for mobiles should be built and has a completely different design.

Flutter is written in Dart, which is kinda ok language. On the one hand, it has every feature possible: classes, generics, overloads, exceptions, futures/async-await/promises/event-loop, garbage collection, JIT/AOT, you name it, and syntactically similar to C/JS/Go languages, so is relatively easy to pick up. On the other – all these features make it really hard to do anything that is not in the tutorials, but the good news, that with Flutter you don’t really write Dart, you write mostly Flutter. Frameworks are the language on top of the language, after all.

Flutter is extremely easy to learn. There is an insane amount of high-class tutorials on every topic, created by the community. API docs are crap, mostly autogenerated unreadable pages, but, again, tutorials and tons of Stack Overflow answers compensate this easily. It took me three days from the time I first read about Flutter to finishing my first app – a mobile app I wanted to make for a long time, but just could not afford to invest time to learn all iOS and Android development intricacies.

Flutter’s design is sick – it renders the app by itself and uses only native iOS or Android (or desktop) code just to talk to the GPU. All widgets, all animations and transitions – all handled internally by Skia, Flutters engine written in C++, and it’s insanely fast and designed from scratch for these things.

Remember how many days we spend chasing Status app slowing down due to switching screens in React-Native? With Flutter, you can do custom crazy animations with 3D effects while switching screens and will run smoothly at 120fps.

Status in Flutter in 5 hours

So, I decided to see, how easy would it be to rewrite that status-react UI part in Flutter. I was mostly interested in the UI part, just main screens – login, register, wallet, chat, profile screen.

It took me 5 hours.

From scratch.

And the app is running smoothly on phones and tablets, Android and iPhone/iPad.

With a framework, I’ve heard about a few weeks ago.

Let me show some quick demo:

Three simulators – Android, iPhone XS and iPad Pro 11

Real device - iPhone XS:

Real device - iPad Pro 11":

The code is available here: https://github.com/divan/status_flutter

React-Native vs Flutter

The main difference between Flutter and RN is that it’s really well designed. It’s not a crappy hack on top of other hacks.

The tooling out-of-the-box is fantastic. You can build the project in one command, and Flutter takes care of underlying layers – cocoapods or gradle. It’s almost Go-like experience when you have flutter tool with subcommands like build/run/test and it does everything you need. Also, IDE support and debugging are great.

To make comparison easier, I’ve made a table:

Flutter RN+CLJ Native iOS/Android
Easy to build Yes No Yes
Easy to learn Yes No No
Has great tooling Yes No Yes
Number of underlying stacks 1(3) 7 1
Need to learn one stack Yes No No
Doesn’t have JS/DOM/CSS bullshit Yes No Yes
Has great success stories Yes No Yes
Has great community Yes N/A Yes
Easy to talk to native layer No No Yes

As you can see, RN+CLJS is the worst option here, at least, at my subjective evaluation.

And, of course, you can say I’m biased, but hey – I wasn’t able to even build status-react most of the time for more then year, and having written already 3 mobile apps with Flutter just for fun in the past few weeks, I can’t even imagine that “flutter app is not building”.

Conclusion

Like it wasn’t obvious, but the current stack of status-react is crap and the worst one on the market. Somehow the core team is comfortable with that for a long time.

Locking chat layer into CLJS-RN code - the code that can’t even be easily built – in hindsight looks completely ridiculous decision. The status app could have been reimplemented dozens of times with different stacks, letting healthy competition to choose the best platform. Instead, it’s piling up more and more of sunk costs directly related to this choice.

I’ll be developing Status Flutter version in my spare time, waiting for the chat layer to be implemented in status-go. Probably that won’t happen soon, but I’m not in hurry.

Just wanted to share how much more productive you can be with the right technology.

For me, it’s an enabler – Flutter lowers the complexity of developing mobile apps to ridiculously acceptable levels – as it should be. It’s the order of magnitude difference if you compare to the native development, let alone to the status-react stack.

If even I can build the main UI part of Status in Flutter from scratch in five hours, I imagine what can do a team of talented developers with great investments. Maybe it’s time to become realistic about RN and CLJS?


Mobile UI for desktop
#19

Incredible, thanks for sharing this! Perhaps extracting the chat from something like status-js, status-x, status-desktop or nim-stratus might be a viable option for reimplementing in Flutter? That helps avoid the complexity of RN stack’s chat layer lock-in and doesn’t force you to wait for a separate API-ed protocol.


#20

Thanks. Yeah, that’s the idea. Due to Flutter’s design (it does render everything by itself, not relying on OS/platform code), in order to talk to the native layer, it requires writing special bridges – “plugins”. It’s no more complex than, writing RN/CLJS wrapper for status-go, however, and gomobile-built libraries (like status-go) can be easily integrated. That’s actually my next step.


#21

It took me 30 minutes (between writing a previous post and this) to figure out how to use Desktop Embedder and run the app on the desktop. Now, desktop support is still under heavy development and require separate building steps for different OS-es, plus small additions of harnessing code to the main function. However, I even added native OS menu support in a couple of minutes.

Status-Flutter on Desktop:

There is also a Google’s project HummingBird – Flutter for Web – they try to find the best way to map rendered image onto web – either by using CSS Paint API, or WebGL or something else. At some point, Flutter apps will run in the browser, with or without WASM.


#22

Awesome to see another implementation! Flutter and Dart make alot of sense if targeting Fuchsia. Looking forward to seeing how easy it is to integrate status-go.

The Nim+Qt approach is also interesting as we can have a tighter integration with Nimbus, smaller binaries and I suspect it would be quite performant.


#23

:smile:

It does make sense if targeting iOS/Android and Desktop first.

Qt bindings for nim (a language nobody’s using in production yet in 10 years of its existence) are literally a single issue for tracking lack of progress.
Flutter, on the other hand, in just two years, created more success stories than React-Native, grown largest community I’ve ever seen in tech in a decade and provides orders of magnitude productivity improvement for mobile dev.
Of course, it makes sense to compare Nim+Qt and Flutter, haha.


#24

https://news.ycombinator.com/item?id=14431315

https://github.com/nim-lang/Nim/wiki/Companies-using-Nim

https://github.com/filcuc/nimqml


#25

Are you supporting or disproving my opinion with those links?

There are few solo devs and indie developers, adding their scripts and couple of browser games to the list of “Companies using Nim” - 9 in total (4 with proofs, mostly IRC chat logs and HN comments "…we’re rewriting one Python script to Nim in our company).

Pretty sad picture for the 10 year old language.

Look, I have huge respect to people who push new boundaries and horizons in tech, fighting dogma and inertia, but doing that doesn’t automatically make technology good or promising or reliable. Nim’s success just didn’t happen, and I don’t know why would anyone assume it should. I hope it’ll find its niche, though.

Ok, QML doesn’t require much bindings, agree. This 3-year old tiny wrapper seems to run helloworld in QML.


#26

But Google is life, right? I honestly have nothing against your corporate fetish, just correcting some falsehoods.


#27

Please, watch your language. You’re just attempting to degenerate the technical topic into childish bickering.

Everything I described about Flutter has nothing to do with the fact it’s made by Google. There is a reason, though, why the projects of that scale and quality are something Google sometimes makes extremely well, but correlation is not causation.

And how exactly did you correct the “falsehoods”, by showing links demonstrating that Nim in 10 years has only a few indie devs using it?


#28

There is one argument presented that I can shed some more light on, having a single developer implement some screens isn’t really that indicative of a projects development speed or success, in Coinhero, Syng and Status we had knocked up the UI and even ported EthereumJ to Android (this is before gox or gomobile was even a thing) in a matter of days.

Infact at devcon2 I said Status was largely feature complete, and it even had unique features that are not present today.

Back then the UI worked well, and alot of things did not, we also had no QA, no UX, no management and much less coordination costs.

The software development process is balancing alot of tradeoffs, some can be seen, many cannot, it’s also just one part of a larger system. Flutter looks nice, but was only released last year. That doesn’t mean we shouldn’t assess it for future use,

Nim is pretty successful in it’s own right, it has a pretty dedicated community and there’s alot going for the language. The difference is really having a solid backing, maybe we will be it when we’re in a stronger position.

I really like the discussion, I hope we can continue it without the attitudes, in all existing & future threads.