Hacker News new | ask | show | jobs
by karimf 1751 days ago
I've been searching a stack which could allow for a single codebase to be rendered in Android, iOS, and the web, and React Native + React Native Web might be the top choice for that. Other competitor includes Flutter, which used to only render canvas on the web, but right now it seems they have an option to render as HTML as well.

I bet the need for cross-platform stack might continue to rise in the future. It's just impossible for small team/solo founder to target 3 different platforms, while handling three different codebases.

9 comments

You might find this recent blog post from the React Native team informative, about their long-term vision for multi-platform support: https://reactnative.dev/blog/2021/08/26/many-platform-vision

From personal experience, I've had great success targeting the 3 platforms you mention in a single RN codebase, with a very high degree of code re-use.

Flutter web has issues with accessibility. They do support screen readers once you enable accessibility by pressing a button, but its rather bad right now. Also scrolling is emulated and doesn't feel great.
I've recently been playing with flutter and I like it more than react-native. React-native feels kind of a hack job, and the resulting program isn't really that well optimized (both performance and size wise). Flutter seems like more thought out solution where react-native was afterthought for react. Both are very productive environments however.
I've had the opposite experience.

The only thing Flutter has going for it is the batteries included aspect, which can be a bad thing as well. I prefer the flexibility of the React stack, being able to match different libraries vs a framework. E.g. maybe you want a more native router, use Wix's native navigation, otherwise use react navigation. Maybe you love reactive programming, use observables, otherwise maybe generators for side effects.

The apps Flutter produces don't feel right, RN does have a more native feel since it uses native primitives. Kinda like wxWidgets vs QT. I'd rather use native controls than trying to mimic the look and feel of native (and keep up w/ changes). This is especially noticeable on iOS and even more so on web.

React Native was definitely not an after thought, it's simply another bridge. I've had great experience with all the bridges. RN for Windows / Mac (both the MS fork and Catalyst), and RN for Web.

I've made and work with a production React Native Web / React Native website and apps. It's been very pleasant to maintain apps and a website (desktop & mobile site) with one codebase.

> I prefer the flexibility of the React stack, being able to match different libraries vs a framework.

No, just no.

The problem with Flutter is that the result is absolutely unusable on web due to rendering to canvas. They implement maybe 2% of the non-appearance features that browsers do for native elements. I haven't heard of the HTML renderer but if that is coming it could be a compete game changer for the viability of Flutter-web outside of games.
I'd like to say imho that Fluttter seams to have the reverse issue from react-native in that it isn't tuned for website rendering. Since Flutter has to redraw it's canvas for animations and user interactions, it can be slow for websites where the browser window is fairly large.
Same here, with the same conclusion. React may not be my favorite web framework, but the native ecosystem blows everything else out of the water.

Desktop support is approaching “okay” (judging by the almost kinda somewhat native feeling flagship app Facebook Messenger on macOS), which puts it many kilometers ahead of any alternative.

The main alternatives for native feeling apps seem to be Xamarin Forms and Qt Quick, the former seems hard to do special things with and the latter has a pretty confusing and convoluted setup process. Neither has real web support.

> kinda somewhat native feeling flagship app Facebook Messenger on macOS

You mean "horribly slow, loses scroll position, can't reliably load and display images, bad click targets everywhere" flagship app?

… yeah. It’s not great. The corners aren’t even rounded. But my gut feeling is that it’s mostly a failing of the Facebook Devs, not React Native Desktop.
More: it doesn't remember window size, takes up to several seconds to apply a custom background to a group chat, and requires a measly 1.1 GB of memory (3.6 GB of real memory) to fail to do all that.

This is the failing of both React Native Desktop and of the Facebook Devs that couldn't even make a rather primitive chat work properly.

Judging from KDE's Kirigami apps and Subsurface on Android, I would not describe Qt Quick apps as native-performing or feeling.
Last time I used Qt Quick, native looking widgets were outside of its scope. You're meant to define the styling you want for all of your widgets, and Qt will render them consistently across platforms.
Out of scope for Qt Quick, perfectly in scope for Qt Quick controls. It looks very native on all the platforms I’ve tried, likely due to their experience with Qt Widgets.
Nice, thanks for pointing this out. Qt Quick Controls weren't around, or at least weren't available on the platforms I was developing against, like 9 years ago.
Because you’re judging one that don’t try. There are demos of Qt Quick apps emulating Android very closely.
What Qt Quick Controls 2 demos on Android would you recommend? Are they pre-built or do they require compiling myself?
I created a tool for those wanting a cross-platform RN app: http://ult.dev/

You can create a project by running: "npx ult ProjectName"

You could use Expo, but I didn't want to be locked into the Expo environment, I wanted native extensions, and I wanted desktop platforms.

For web it uses a lite forked CRA project tailored for React Native Web. For native it runs the proper commands and sets up all the platforms for you.

Currently ReactXP is the default as it's more stable and feature complete, but RNW is supported.

In the future RNW will be default as ReactXP is abandoned and RNW is the clear winner.

Cross-platform frameworks work great for basic CRUD apps but when you start to do things more complicated it can be a headache. Sometimes hardware and features you want to leverage are specific to the platform.
With React Native you can just use file.ios.js or file.windows.js etc if you want to do something different entirely for a platform. You can also check the platform with a function for minor adjustments. You can also handle these differences in a RN extension if they involve native code.

You can model your codebase so the function stubs are the same, but the implementation differs based on platform. So you can use it the same way in the rest of your code.

I run this setup in production and I share about 95% of code between platforms for a complex cloud storage app (file manager, uploading, etc.)

Basically isolate what's different, and abstract it to a common interface.

> With React Native you can just use file.ios.js or file.windows.js etc if you want to do something different entirely for a platform. You can also check the platform with a function for minor adjustments. You can also handle these differences in a RN extension if they involve native code.

Well if you need a specific widget or library that react native doesn't support by default you have to write bindings, and unless your business logic is very basic it happens most of the time. You might be lucky somebody already did write some bindings for you. As someone that used Titanium in the past, React Native suffers from the exact same problems.

Not really as you'll have to do that work anyway if it doesn't exist. It's better to do a small extension than to duplicate all of your other shared code just to do that change.

Most of the time there will already be a 3rd party extension, but it's really easy to make them. You will need some slight native experience, but you would need more for a full native app.

With Titanium it wasn't easy to do these extensions, with RN you have direct access to the native platforms and code. You can go as native as you want in one or all platforms while sharing the code you want to.

Point being these are leaky abstractions. You have to have some measure of knowledge as to how the underlying platform works in a professional context.
The abstractions depend on the dev. The knowledge needed is considerably less to make an extension vs making a full native app.

RN is useful if you're a solo dev, like myself, or a small team and you want to support all platforms.

I have enough knowledge to get all my apps in production, enough to make extensions for the platforms, and quite a bit in web to remake native features on the web. I am not what I consider an Apple or Android dev though, far from it.

I can learn from a middle out approach when it comes to all platforms. Similar to compilers and such, you can always go lower level to understand more and more, but it's not needed to get your vision out.

I'm a solo developer, and I have a project that totally can do it. I've done the proof-of-concept in an afternoon, but am mostly focused on web stuff atm.

Granted, it leverages NativeScript, but it's really not that hard once you have that.

Could you please share the details? I don't know about a way to render the same template in the browser and nativescript.
In my case, you basically just take some code like this:

    const renderEl = flex("UserList", [
      label("User", ["Alice"]),
      label("User", ["Bob"]),
    ]);
In NativeScript, you would have these functions create those types of UI elements. For web, they'd probably produce divs and spans.

Ofc, there will be certain elements that are native only, or require really special stuff to create.

I wonder if Apple would ever throw their hat in the ring, I don't think they appreciate Facebook and Google dominating the space when they try to push developers to use Swift
Check out my SnackUI in my GitHub, I built it to improve in a lot of ways on the single codebase use case.