Proton Native – React Native for the desktop
proton-native.js.org
proton-native.js.org
It doesn't serve the author well to make this comparison. Saying it's less messy to manage Proton/React source code files and the associated Node/JS/etc infrastructure is an extremely dubious claim. One of the things I like best about Qt is how non-messy Qt development is. Most everything (source files, resources, etc.) lives in a well-organized project that is easily managed using the Qt Creator IDE. The project structure is well-documented and standardized.
It's also quite strange to compare React code to code using the Python binding for Qt. That's not how most Qt apps are written. Most Qt apps these days use QML, which is based on regular old JavaScript. Besides being a more accurate representation of the way Qt development is normally done, it would also be more interesting to compare one JavaScript-based framework to another. (Although I recommend not making the comparison at all, since I don't believe a fair comparison would favor Proton.)
import QtQuick 2.9
import QtQuick.Controls 1.3
ApplicationWindow {
title: "Example"
visible: true
width: 300
height: 300
Button {
text: "Button"
anchors.centerIn: parent
onClicked: console.log('Hello')
}
}I may be biased, but to me the QML code is much cleaner and clearer than JSX.
(Think of an Item as a visual component, which can either be referred to by an id or, as I've done here, referred to by its children as "parent".)
Item {
property int count: 1
Button {
height: 30; width: 80
onClicked: parent.count++
}
Text {
height: 20; width: 30
text: parent.count
}
}
The text will update every time you click the button.What's nice about react is that the JSX syntax is just sugar that converts to function calls.
The standard way to do this in QML is using the Loader object: http://doc.qt.io/qt-5/qml-qtqml-component.html
You can also go full-eval of course: http://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation...
You have been able to bind closures to events in Qt for... dunnno... 6 years maybe ?
View = fn(state) solves longstanding issues with all the previous approaches, and of course it decreases their complexity. It is also the first approach that's breaching the platform barrier successfully while maintaining the high-level. You can write React for countless of targets, being able to re-use and apply the eco-system.
Could you please paste an example of a real, functional QT component? For instance a component that is re-used in another component,
const A = ({ text }) => <div>{text}</div>
const B = () => <A text="hello" />
<B /> // -> <div>hello</div>
as well as functional composition (higher-order-components): const canBeDisabled = Component => props => props.disabled ? null : <Component {...props} />
const ComposedB = canBeDisabled(B)
<ComposedB /> // -> <div>hello</div>
<ComposedB disabled /> // -> null
an example for statefull components would also be nice: class C extends Component {
state = { count: 0 }
up = () => this.setState(state => ({ count: state.count + 1 })
render() {
return <div onClick={this.up}>{this.state.count}</div>
}
}
<C /> // -> <div>0</div>, clicks count up reactively Text {
property int count: 0
text: count
MouseArea {
anchors.fill: parent
onClicked: count++
}
}
if you put this in a file `C.qml` or load it as a component (http://doc.qt.io/qt-5/qml-qtqml-component.html), then you can reuse it in other components: Item {
C { }
C { count: 23 } // starts at 23
}
For your functionally composed example, all qt objects have a `visible` property so you'd generally do : MyItem {
visible: props.disabled
}
Note that unlike React, the "default" paradigm is not functional : in QML you describe directly a dataflow graph between the properties of your objects. e.g. C { id: myCount }
Rectangle {
color: "red"
// the width will change whenever the count increase
width: Math.cos(myCount.count) / 2
}
This is because the objects with which you work in QML are exactly the ones that are going to be rendered - and at a fairly low-level: they mostly translate directly to GL / D3D primitives ; there is no need for a transformative pass like with react.There is a major difference between that and Reacts approach.
const A = () => <div>...</div>
const B = () => <h1><A /></h1>
Notice that the B component can refer to the A component because it's in the same scope. There's no magic and no binding/loading. A is a function that is called inside B's function body. It also isn't done by inference of an ID (which would be registration).Yes, an equivalent in QML would look like this if you want it in a single file:
Component {
id: a
Text { text: "foo" }
}
Component {
id: b
Rectangle { Loader { sourceComponent: a } }
}
but the language really wants you to have one component per file, so : A.qml:
Text { text: "foo" }
B.qml
Rectangle { A { } }
> if QT is the same,It's not. QML is at its core not a functional language, it's a declarative & reactive language. In my experience, at least 30-40% of QML code does not need any functions.
> There's no magic and no binding/loading.
I'm not sure we are using the same meaning of binding. The "A" token in your example is obviously bound to the "A" variable declared before.
> It also isn't done by inference of an ID (which would be registration).
ids in QML are just the variable names. eg
Rectangle {
A { id: foo }
width: 2 * foo.width
}http://blog.qt.io/blog/2018/04/13/qt-for-python-is-coming-to...
License-wise: "Qt for Python will have the same licensing as Qt for Application Development, i.e. it will be available under GPL, LGPL and commercial."
Have they got the data grid API's working yet?
The data grid has still problems on macOS unfortunately, but @andlabs is working on it...
Seems to me that this should use far fewer resources (especially memory) and make it easier to make an App look more 'MacOS'y. Very eager to give it a go!
https://i.imgur.com/g94LOvE.png
It uses around 35MB.
For the comparison, IDE sketch (editor with syntax highlighting) from Sciter (HTML/CSS/script engine) SDK (https://github.com/c-smile/sciter-sdk/tree/master/samples/id...) takes 43 MB.
Screenshot: https://sciter.com/wp-content/uploads/2018/05/idea-ide.png
Resource measurements: The sample "Notepad" app (just a text box in a window, no copy/paste, etc.) uses 79 MB. For comparison the same app built using Xcode uses 27 MB, and TextEdit uses 40 MB.
Not that I'd be concerned about a few tens of MB nowadays but on the whole we're consuming computing resources at the same rate faster hardware is put out (Gates' law).
I have a Pentium 3 running NT4 sitting on the same desk and it is faster at many tasks than my i5 workstation. Visual Studio 6 especially is super snappy. How then can Slack, on a machine with an order of magnitude more processing power and 64 times (!) as much RAM lag when switching channels?
Anything that could fix the current situation even a little bit like this project is much appreciated imho.
This craziness just made me buy Sublime Text.
I'd bet Slack, for example, has all sorts of abstraction and indirection layers in it, making it impossible to figure out the fastest way to do the job.
I do wonder why nobody takes a stab at creating a bonafide Excel clone that looks modern and runs fast (and, no, LibreOffice isn’t good enough).
The app logic is still in Javascript, never compiled to another language.
IMHO this is perfectly fine. I have a fairly large app in react-native, and most users that have tried it are fine with its performance. Scrolling in lists and maps, being native components, is as snappy as in a real native app. I'm only having performance issues in page transitions, and I think I can fix that with a bit more work.
Haven't we moved past writing UIs in code about twenty years ago? I see your code samples, and all they look like is an improved version of the code UI creation we had in OWL, MFC, and other UI frameworks on other platforms.
Starting about 1995 we had a better way: form designers that streamed objects (note: not even auto-generated versions of code, which is not much better, but object streaming.) Your UI is then designed and manipulated largely as a graphical UI -- that's what it is -- and manually written code is reduced to tweaks or state changes.
For example: Delphi (the prototype of all modern UI frameworks); C++Builder; others. WPF may count although the generated text is ugly as :) - but it carries the concept. A NIB file on macOS. You get the idea.
I'm working at Pagedraw (https://pagedraw.io/) which attempts to solve this problem. We make a UI builder for web. It pretty much works like all the UI builders of the past, but translates constraints into divs, flexbox, and other web standard html/css. We don't have the benefit other UI builders in the past have had of compiling into our own layout system, because we refuse to force our users to use a js-based layout library or take extra dependencies which could increase bundle size.
It's only available for React Web for now, but we look forward to supporting React Native, and maybe even Proton Native in the future!
Lastly to matchbok's point:
> NIBs in macOS/iOS are horrible for development and code review.
We hope that this is a problem with NIBs, and not with UI builders in general. We believe that it's because there are no NIB diff/merge tools, so we're building branch/diff/merge into Pagedraw as a first-class feature.
Well you can always choose to roll your own layout algorithm and position everything in the DOM using absolute coordinates - e.g. https://diasli.de implements an 'auto layout' mechanism disregarding DOM layout.
Using a UI to build UI is slow and clunky. There is no "moving past" it. That's a bad way to develop stuff. We don't do it with HTML, do we? No.
Storyboards are great - they simply force separation of concerns among developers.
One person handles one part of the app, and other people keep their hands off of it.
Each person has their storyboard/collection of nib files.
Multiple people should absolutely not be tinkering with the same files randomly - obviously I hope.
As for things rearranging for 'no reason' - it'd help if people took 2 days to understand auto layout. Every person I've ever met who dislikes sql, or storyboards/auto layout etc, simply doesn't understand what is happening.
It's trivial to create a mess in auto layout, if you don't know what you're doing, just like people create cocoapod soup in every other iOS project. There is no silver bullet for curing mediocrity - just make sure you're not part of the problem :)
I review design screens and UI/UX workflows with end users.
But to arrange the view controllers and segways + some static tables it is mighty fine.
WPF has(d?) this figured out. No drag and drop of UI elements (aka "components"); that gets you into "absolute position" hell of Windows Forms. Instead you have a DSL that you use to build the UI with grids and other standardized layout containers and the WYSIWYG view is there mostly as a preview and navigation help.
Of course their fatal mistake was having no code whatsoever in the DSL. They wanted to make it so designers would use it; designers will never use anything but Photoshop, so the other half of them that isn't resistant to learning now calls themselves frontend developers. The model binding on steroids helped some but still "inverting" an enum required 15 lines of code somewhere else to create a converter.
Only for those that never bothered to learn how to use Window Forms layouts.
https://docs.microsoft.com/en-us/dotnet/framework/winforms/c...
It's the same issue that project.pbxproj has in Xcode.
How could we? There is hardly any design tooling that matches the capabilities of native ones.
So we just give up and pretend we don't need them.
This is what I love RN so much - I can build UI in 20% of the time and effort.
Here's an interesting discussion of Delphi (2013): https://news.ycombinator.com/item?id=7613543
First, you have a visual form designer: drop a button, resize it, edit the caption, etc.
All objects like buttons, edit boxes etc are classes with properties. They live on a form, another class. The key is object streaming.
The form has instance variables: a private MyButton : TButton, for example, where TButton is the type. This list of fields is autogenerated by the IDE. However, those are created and values set not in code or managed by the IDE, but by loading from a human-readable text stream at runtime (stored as a separate file at designtime, and linked as a resource at compiletime), something like, from memory:
Form : TForm
Button : TButton
Left = 100
Top = 50
Width = 70 // etc
Caption = 'Hello'
OnClick = MyClickHandlerMethod
end;
end;
When the form loads, the object instances and their properties are created and set on the fly. A form will self-initialise it and its owned objects from that stream: it will create a TButton instance, assign it to its own Button field, set the Left and Caption properties for the button etc. That includes hooking up methods to events, which are just properties of a method pointer type. So effectively, you have a human-readable, easily editable format that is a streamed version of a class and instance/property hierarchy, which the class can recreate itself from. That is generated by a visual editor, and of course you can edit it manually. It is a very simple and clean format; as little as possible is stored. It is also very diff-able.Your code then is reduced to things like state changes or events - user clicks a button, you write code to do something.
UIs are visual. Writing a complex UI in code is inefficient (manually doing stuff you should not have to do) and with a long modification turnaround time - you can't preview what it looks like, so changes take a long time. The important leap was to design visual elements visually; to stream, so it is OO, diffable, and still human editable if you need to; and to load from a stream via reflection/RTTI.
Delphi did all that in 1995. C++Builder does all that too, in C++! It's beautiful compared even to Qt, and certainly compared to code like the original post, which reads like early nineties techniques to someone used to the above.
Allaire Homesite (one of the early HTML editors), written in Deplhi, was one of the first apps that openly ignored the pt sizing and was broken on computers with Large Fonts setting enabled. After that, everyone started ignoring the DPI, and that is what got us into today's HiDPI mess.
Yes, I was pissed of at the time. I was using Large fonts. During a short time, that option became unusable, because nobody bothered with DPI, when drag and drop UI design is so easy.
I don't see an issue with creating UI's in code, with a decent API like Qt and Gtk provide it's quite straightforward. Why should UI code be treated differently to other code?
Why should I spend 30 coding something away that is doable in a few seconds with a couple of mouse clicks?
It is not good to generalize, but most coders I have meant without any sense of UI design never used graphical tooling for doing UIs.
Because maintainability is more important than instant gratification. If you can do both then great, but IME visual designers are a maintenance headache.
Changing a couple of properties in layout files is more maintainable than hundreds of code lines just to change a visual effect.
If you need to do that, your codebase has a serious problem.
I remember using GUI codegen tools in the 1990-ish era that would blow away your code changes with every GUI tweak. Interface Builder and delegates were a great solution to that problem. I just didn’t get to use them for a really long time.
It's been like that on Windows since 2006 with XAML. In fact, if you squint at typical JSX, it looks like XAML.
Disclosure: I work at Microsoft.
The crazy part is, that you can share code and eco-system components among these targets, no matter if they're native or otherwise. Here's a shell applications for instance that uses react-motion to shift stuff around: https://github.com/gaearon/react-blessed-hot-motion
Microsoft seems heavily invested in it as well (react-windows, reactXP, UI-fabric, ...).
What does dependency injection have to do with anything? There's nothing stopping you from using global variables or an event bus or something like Redux in a XAML app.
OpenLaszlo was most immediately inspired by HTML and (for data binding) XSLT. I looked at Mozart for ideas on constraints, but we ended up rolling our own design — mostly because constraints were never supposed to be a feature, so they were designed and developed incrementally, in discretely releasable baby steps.
Adobe did due diligence of the company sometime around 2002-2003 too, but that deal fell through. An Adobe PM also signed up for our beta program, initially under a pseudonym, but he eventually came clean. I’ve always been curious whether Flex/MXML was related to either of those encounters.
[1] https://en.wikipedia.org/wiki/OpenLaszlo
[2] https://ssl.weepee.org/lps-4.6.1/docs/developers/program-dev...
This was the bottom of a slippery slope, where the designers and developers using the platform were exploring the kinds of applications it was possible to write (single-page web applications were relatively new in the early oughts — except for some pioneering Explorer-only DHTML work by Microsoft, which we should have looked at but didn’t — and we were all making up interaction patterns and software design idioms as we went along), and we were adding the platform features to enable some capabilities and golf others.
For a while Adam ran Laszlo’s Professional Services. He succeeded me as CSA when I left Laszlo.
It wasn’t Flex/MXML or XAML that killed Laszlo/OpenLaszlo, it was IMO first-gen dynamic frameworks such as Prototype and Scriptaculous, that could be gradually integrated into a page without placing a big rewrite-your-app bet. Also that we were about a year late in adding HTML as a second back end. (HTML wasn’t sufficiently standardized or practical to use for cross-browser single-page applications in 2001 when we started work on the Laszlo platform implementation, but it was by 2005-6.) Or, closer to the root cause: sales and strategy issues that made it difficult to keep investing much in the platform once it was starting to get traction; the product feature omissions are how those resource constraints played out.
[1] https://patents.google.com/patent/US20050039165A1/
Today Xamarin does all this pretty well cross platform, desktop and mobile for UWP/Mac and iOS/Android.
The databinding approach is both elegant and familiar.
It certainly does look a lot like Vue Single File Components if you squint.
Damn it, didn't we just have an article on HN about creating art using CSS?!
At least when concerning all major GUI libs.
It's more like a markup driving an immediate-mode graphics API.
It works I suppose, but it's very clearly written to be an easy-to-compare example, not a realist example. To really get an idea of what it would be like to use proton native v. Qt I'd like to see a small but complete project.
Easier to read and edit is obviously subjective, but shorter is not and that front page is just straight up lying. The Qt example is most definitely shorter. What am I missing?
But if you have any suggestions let me know!
It seems to me you're making a syntax comparison and using shorter as an argument for Proton Native, yet the example is obviously not shorter so it's factually incorrect. My suggestion is you don't use shorter as an argument. Aside from being incorrect, it's probably not very useful since a few characters here and there doesn't necessarily mean one is more or less complicated than the other – which I presume is what you're really trying to convey.
I'd probably refrain from using syntax comparison (mostly a matter of preference and familiarity anyway) and instead show why Proton Native is obviously less complex than Qt (or other options, if that matters.)
import QtQuick 2.7
import QtQuick.Controls 2.2
ApplicationWindow
{
title: "Example"
Button {
height: 300
width: 300
x: 50
y: 50 // not represented in the react code for some reason
onClicked: console.log("Hello")
}
}Menu {
title:qsTr("File")
MenuItem {
text: qsTr("&Open")
onTriggered: console.log("Open action triggered");
}
}I’m talking about this:
</Button>
</Window>
</App>
);
}
}Also, the paradigm is completely different in that react is React is déclarative whereas Qt, in this mode, is procedural. I would argue that QML would be a better comparison, and in this case I’m quite sure that qml wins.
So much for buzz words..!
import React, { Component, createElement as e } from 'react';
import { render, Window, App, Button } from 'proton-native';
function Example() {
return (
e(app, {},
e(Window, {title:"Example", size:{{w: 300, h: 300}}, menuBar={false}},
e(Button, {stretch=false}, onClick={() => console.log('Hello)}, 'Button')
)
)
);
}
render(<Example />);
If you really hate the brackets and parens you could certainly use a dialect of JS that doesn't have them, and you could cut it down to like half the length of the Qt example.But this whole discussion is silly. "Shortness" in code terms has much more to do with the number and complexity of statements, not LOC or characters. The JSX in there adds "noise" and characters, but the whole purpose is to simplify understanding code and make it readable. It's not adding any fundamental length.
The Proton example is doing a bit less than the Qt example, and for me that's a much more useful definition of shorter.
Sure, if you swap in another example that is in fact shorter, then it'd not longer be an incorrect statement. Maybe I am indeed being silly, but it seems getting the hook-line-sinker arguments as right as possible is a worthwhile goal, particularly when at least one of them can be objectively verified.
If by "shorter" you mean "less complex" than stop saying "shorter" and start saying "less complex" instead – just as you say they aren't the same thing. It'd mostly be redundant I guess, given "easier to read" and "easier to edit" implies "less complex", but at least it'd be harder to immediately refute.
import QtQuick 2.7
import QtQuick.Controls 2.2
ApplicationWindow {
title: "Example"
Button { height: 300; width: 300; onClicked: console.log("Hello") }
}
look ma, 6 LOC !And according to their announcement post Litho is what they are using for their News Feed: https://code.facebook.com/posts/1187475984695956/open-sourci...
So the most critical part of the Facebook app isn't in React Native. How much of those other apps are actually using React Native?
The Android version is just RxJava, iirc, because of some performance issues they couldn't get around.
[0] https://blog.discordapp.com/using-react-native-one-year-late...
Of course, with unlimited development capacity, for each React Native app there could be a better purely native app.
Another point also often forgotten is that the user experience of a React Native app, while not as 'platformy', will be very coherent for users of multiple platforms. That can also be considered as 'better', given you are such a user.
https://github.com/wix/react-native-navigation
Edit: Replaced the word FUD with overstated, to not seem like I'm attacking the author personally.
"The last time I checked there was still no reasonable, scalable way to do complex navigation on the platform. Most third-party components are unusable six months in due to API changes."
The links are counterpoints to the complex navigation issue. Showing that libraries exist and can handle complex navigation. If you want to argue that they are going over rapid change, which is true, then that is another thing. But I'm gonna disagree with the blanket statement of "there was still no reasonable, scalable way to do complex navigation on the platform" as overstated.
As for the second point. I assume what you mean by 'third-party components', is actually third-party native modules. In which I agree the API for them doesn't seem to have stabilized yet so there is a lot of churn in native modules. But a lot of third-party components I have seen continue to work in newer versions of React Native.
Just a nitpick because I think "FUD" borders on ad hominem in the way it's sometimes used.
Again, as a React dev, I haven't encountered the cited issues and they seem a little dated, but I wouldn't call them FUD.
It's iOS-style navigation and transitions through and through.
You got me :) But yes, I'm in a lot of these threads because I do a lot of iOS development and have strong opinions on how iOS apps should work.
> The thing about the link you just pointed out is that it's literally 100% UINavigationController. I've used this in projects and had to work with the native source layer - it's nothing crazy different. > It's iOS-style navigation and transitions through and through.
UINavigationController is a complex beast that is often difficult to work with even in native code, because it tries to do a lot of things for you that are difficult or outright impossible to replicate if you try yourself (which isn't necessarily a good thing, but that's what we have so that's what we need to work with). Plus, a lot of this behavior "comes for free", but the downside to this is is you customize certain things you give up a lot of this behavior. So UINavigationController is not just showing a title and a back button in a box: it does things like managing transitions, animating the title when pushing onto the navigation stack, handling popping gestures, handling content insets and vibrancy, and providing certain niceties such as "tap the top of the screen to scroll up". It's a lot of things to keep track of, even for native developers, so while I'm not saying that this can't be done in JavaScript often a lot of this just ends up being reimplemented in scratch and you end up missing things. For example, the provided link, from a cursory glance that navigation controller completely butchered title handling and animations. If you want to take look at how these should work, take a look at Settings or Mail and see how the behavior differs.
All the JS in that package is doing is driving the native interactions on an in-memory UINavigationController. I've used this in recent contract work where I can confirm that the title handling and animations are the same as what you'd get with a stock UINavigationController. That project is not replicating the behavior in JavaScript, contrary to what you seem to be implying - e.g, tapping the status bar does indeed scroll shit to the top. It's all driven by JS that simply calls the native layer code.
There are a lot of reasons to prefer the Apple dev ecosystem on a native level, but this is a moot point at the end of the day.
Finally, look... I was your age once, and believe me, I too thought I was an expert when I was in high school. Age and time are gonna show you otherwise sooner or later. Blind allegiance to a particular tech stack isn't healthy for your career, and throwing this stuff in every thread you find just gives a really bad image to projects that are starting to beat [Apple/Qt/etc]'s dev environment at their own game. These environments need to step up their game to stay competitive, and plugging your ears (and giving this fodder to everyone else) and pretending otherwise isn't helping anything.
This is almost willful ignorance on the level of Twitter's Cocoa community.
I'm aware of that–that's why I said it is possible that you can do it from JavaScript. What I'm saying is that the JavaScript layer generally causes issues like this, because UINavigationController only works in specific cases. For example, scrolling only works if you're a singular top-level scroll view. Getting the titles to animate only works if you don't try to modify it after the fact. Putting a button in the navigation bar's title view just makes it mess up when it runs its first layout pass. A lot of frameworks end up doing this, or making it very easy for this to occur, so you end up with "broken" navigation of the likes seen in that GIF. Of course, it's not unusable, so those who aren't as familiar with how it should work don't notice the difference.
> Blind allegiance to a particular tech stack isn't healthy for your career
I'm surprised you haven't drawn the cynical conclusion from this: that I'm desperately trying to keep my skills relevant in a world where they're being increasingly obsoleted (if you were wondering, no, this isn't true. I do have other skills as well, not including the uncanny ability to get into arguments on the internet ;) ) Thanks for the advice though, and I do mean that sincerely.
> throwing this stuff in every thread you find just gives a really bad image to projects that are starting to beat [Apple/Qt/etc]'s dev environment at their own game. These environments need to step up their game to stay competitive, and plugging your ears (and giving this fodder to everyone else) and pretending otherwise isn't helping anything.
Wait, are you really telling me to stop "putting down" non-native projects? Am I that persuasive that I'm giving fodder to other people? I'm really not trying to be argumentative here or pushing any sort of agenda; I'm just really, really sick of people pushing out terrible web apps that they call "native". As a developer, I agree that these projects have better tooling (Xcode isn't a particularly high bar to clear, though), but as an end user, I really hate these projects because they're clearly oriented towards developers rather than me. As someone who largely writes software for themselves, the idea that you'd make tradeoffs that harm your users is just morally appalling to me. It's not the environments that need to step up their game: it's developers who need to realize that the user is important. Sure, use JavaScript or Qt or whatever you need, but not because it makes your life easier: do it because it improves your user experience. If Cocoa just decides to mine bitcoin on your computer tomorrow I'll switch in a heartbeat, since it benefits my end users.
> This is almost willful ignorance on the level of Twitter's Cocoa community.
Sorry, I'm not on Twitter, so I'm not aware of what you're talking about here. Could you provide more context?
Most of those issues that you bring up with UINavigationController are, while annoying, not actually _that_ common in apps, and people run into them at the native level too - it's not entirely a JS issue. Provided you're not doing anything too against the grain (which the Wix API more or less protects novice users from doing), you're unlikely to experience too many issues and it functions as an almost completely indistinguishable UINavigationController experience for pretty much everyone.
As an aside, if React Native would fix TouchableOpacity to follow platform convention, most people would have difficulty detecting RN apps.
> I'm surprised you haven't drawn the cynical conclusion from this: that I'm desperately trying to keep my skills relevant in a world where they're being increasingly obsoleted...
I didn't draw that conclusion, you're correct - but had it been the case, I really wouldn't have blamed you. I prefer writing [UI|App]Kit day to day and I'd hate to not be able to. I'm more than capable in... just about any programming ecosystem, but they're simply not as enjoyable for reasons that are tough to put into words.
>Wait, are you really telling me to stop "putting down" non-native projects?
No, not at all. I put down Qt all the time myself, but then again, how do you define native? ;)
My point here is that coming into these threads and saying that people should be building native iOS/macOS/etc is a bit of a rough sell, given how nuanced actually developing at the native level for those platforms is (e.g, most people wouldn't know that a UITableView section header is really a grouped row in NSTableView - AppKit is woefully undocumented and cobweb filled in 2018). Apple needs to get their shit together, and maybe that's what Marzipan or whatever is - in fact, I really hope it is.
Until then, there's simply no compelling reason to build native [UI|App]Kit when the writing is on the walls. Instead of fighting this battle, people need to complain (loudly, very loudly) to Apple. Electron & co are not taking over because they're inherently better as an approach, but because native platforms are literally just rolling over.
>it's developers who need to realize that the user is important
This is idealism, and I applaud you for it, but it's honestly misplaced (and I wish it wasn't). The user is only important _when you actually have users_. For most apps these days, time to market and getting it out the door trumps whatever perceived native benefits there are.
I personally build for quality in my projects because it's what I want representing me, and that's sadly about the only justifiable reason these days.
>Sorry, I'm not on Twitter, so I'm not aware of what you're talking about here. Could you provide more context?
Was a bunch of hubbub recently over this article (http://inessential.com/2018/04/25/youre_practically_a_mac_de...), where it boiled down to Xcode/Apple-ecosystem developers decrying alternative approaches (Electron, RN, etc), and more or less saying that it should be easy to just reuse the same stuff for a Mac app. The argument that most non-Xcode/Apple-ecosystem devs made was that Apple:
- Really, really sucks when it comes to Mac/AppKit documentation these days, and discoverability in comparison to the likes of JS and such is nowhere near the same.
- Live reload > compile and run, Swift playgrounds aren't a solution.
- [Almost any JS unit testing framework] > Unit testing in Xcode
The tl;dr = Apple is getting off relatively easily for not keeping their dev environments competitive, and people complaining about Electron & co making inroads should really be complaining at Apple for neglecting this stuff. I tend to agree, as noted earlier... and, hell, it's not even limited to the above points.
For example:
- Why the hell are the Apple forums not scrapped and dumped into a hosted StackExchange? It's 2018.
- Why the hell is Radar still a black hole of information? There are better ways to do this nowadays.
- Why the hell is so much of Cocoa & AppKit completely un-Google-able? Half the time you try to find something, you wind up in an archived email thread from the early 2000s. There is no way a new developer is going to put up with this crap in 2018. Shit, if it wasn't for NSHipster transcribing WWDC videos we'd still be sitting there watching video content just to understand a programming ecosystem.
- Why the hell does every Cocoa/AppKit dev put all their stuff on Twitter these days? They're just as responsible as Apple at this point. The JS community documents the everloving bajeezus out of their projects, whereas the only mention you'd find about, say, NSCollectionView frame/bounds change notifications is on Twitter. Nothing from Twitter is easily found in Google.
- This list could go on - e.g, why the hell are we _still_ dealing with Cells in AppKit for things like a TextField? We got rid of them for NSTableView, fix the rest already.
What's really painful about all of this is also that Apple is clearly capable of doing better - Swift alone is a massive improvement in how they've communicated, built, and shipped a developer oriented product. People not holding them accountable and instead expecting the developer community to bend over backwards and build for an aging platform is insanity, especially when this is the most valuable company in the world that we're discussing.
* = Edits are formatting attempts, because... well, this is another platform that could modernize a bit.
Yes, but as I've mentioned, JavaScript makes these issues more prominent because it's a lot more likely to get into one of these "invalid" states that breaks UINavigationController. And I disagree you with your claim that it's not noticeable.
> how do you define native?
.NET on Windows, Cocoa on macOS, GTK+ on Linux, Cocoa Touch on iOS, and the Android SDK on Android.
> The tl;dr = Apple is getting off relatively easily for not keeping their dev environments competitive, and people complaining about Electron & co making inroads should really be complaining at Apple for neglecting this stuff.
OK, but I don't think the right solution to this is trying to threaten Apple into making the development environment better. Really, you just end up making a bunch of terrible apps and your users hate you for it. And a lot of the things you bring up as being "terrible" aren't really that bad, known to be actively being worked or don't really have an easy solution. Apple forums are not on StackExchange because that's not hosted by Apple. Radar is a black hole because if it wasn't Apple would leak confidential information (though, of course, they _could_ make this a lot better by separating Bug Reporter from Radar). WWDC videos already have transcripts. AppKit is due for a overhaul this year or the next with Marzipan. Swift (and with it, Xcode) is moving towards being more open.
Which is cool and all, but most people on the end-user spectrum don't notice it, which is good enough for most companies. Thus, "an almost completely indistinguishable UINavigationController experience for pretty much everyone."
>.NET on Windows, Cocoa on macOS, GTK+ on Linux, Cocoa Touch on iOS, and the Android SDK on Android.
Beyond the fact that my point re: what's native was a bit tongue-in-cheek... GTK+ isn't even necessarily the default for Linux/BSD.
>Really, you just end up making a bunch of terrible apps and your users hate you for it.
No, _some_ users hate you for it, typically a very vocal minority. Slack doesn't grow to be as valuable as it is without being usable and enjoyable for most people.
>Apple forums are not on StackExchange because that's not hosted by Apple.
This is a cop-out. There is nothing stopping them from aping the entire system, and Apple's forums need to be put in the ground. This is a known issue, even the Cocoa crowd on Twitter has recently agreed with this point.
>AppKit is due for a overhaul this year or the next with Marzipan.
Marzipan isn't even the official next move, and nobody outside of Apple is sure what it exactly is. The point I was making is also slightly different - there is absolutely no excuse for the neglect that AppKit has seen over the past ~10 years, and anyone complaining about Electron/et al should be criticizing Apple for not keeping AppKit competitive.
This literally is UINavigationController, controlled by Apple's JavaScriptCore.
If you want extra animations or whatever, you just turn them on.
There are some advantages to using native code vs ReactNative, but access to native controls and their behavior isn't one.
But in short: yes, you're right. React Native uses native controls, and it's probably the best solution right now. That doesn't make it good enough in my eyes, though. I want apps that I can't tell apart from "real" native ones. With Reactive Native I can do so almost invariably, and it's because someone forgot to "turn on" an animation or whatever. Or it's because they clearly just didn't understand the UI paradigm that iOS enforces. Or it might even be more insidious: React Native was just structured in a way that made easy to do the wrong thing. Whatever it is, it's clear to me that React Native still doesn't match native controls, and no, this isn't because they don't use them. It's that they use them wrong.
If this project was about formalising proper stable support for Windows and macOS within React Native, that would totally make sense. But it seems more like it's trying to be an alternative, under a different name, different branding, etc.
Surely it's better to remain as one widely compatible project?
And what if you want to make a non-UWP app for accessibility or other reasons? Just your standard, straight forward Win32 GUI. Bringing the power of React to that space will still appeal to many.
WPF and Win32 are not the same thing.
I'm not sure why JIT is relevant. Neither JSC nor Node do any JITting.
http://thibaultlaurens.github.io/javascript/2013/04/29/how-t...
One thing to note, the naming convention of props differs from React Native which is a bummer. https://github.com/kusti8/proton-native/issues/9
IIRC the project is a light mapping from libui-node project to React.
BTW: It should be "protons" without an apostrophe.
class Example extends Component {
render() {
return (
<App>
<Window title="Example" size={{w: 300, h: 300}} menuBar={false}>
<Button stretchy={false} onClick={() => console.log('Hello')}>
Button
</Button>
</Window>
</App>
);
}
}
render(<Example />);
is using too many artificial parsing layers ?1) Like run JS, then there 2) parse JSX that will build virtual DOM, then 3) interpret that vDOM to 4) create physical window.
Why not just
let app = Application({params});
let window = app.window({url:"content.xml",
type: "frame" }); let button = new Button("Click me");
window.attach(button, {position: 'center'});
To me, imperative widget creation gets tedious and hard to read pretty fast. I'm not a fan of the many parsing layers involved in the JS example either, but I really appreciate the declarativity they enable.Window content can still use markup. But it is not clear why do you need it for defining Application and Window abstractions.
In browsers DOM element is a subject of style applicability and events handling. But why do you need DOM nodes for application and window ?
window = (...children) => <App><Window>{...children}</App></Window>
Over the years I've learned that some boilerplate isn't bad. In fact it means App and Window are implemented in the same abstraction that I'm using. import { createElement as e } from 'whatever'
return e(App, {}, [
e(Window, { title: 'Example', size: { w: 300, h: 300 }, menuBar: false }, [
e(Button, { stretchy: false, onClick: () => console.log('Hello') }, [
'Button'
])
])
])It is not, https://facebook.github.io/jsx/
It is handled by transpiler - one more parsing layer in loading sequence of your application.
[1]: https://developer.mozilla.org/en-US/docs/Archive/Web/E4X
There's already plenty of prior art for RN-compatible projects that target non-mobile devices (e.g. react-native-web, a half-dozen different AR and VR projects).
Sidenote as for why a UI library would wrap another UI wrapping library, Gtk is what is considered "native" on Gnome based distros.
So weight-wise, it's basically comes at the cost of native node module which is not bad compared to Electron's crazy IPC bridge back and forth communication nonsense.
And now with NAPI [1] it should be easier than ever to make node modules!
Is still really incomplete compared to libui-node, but just in case someone wants to help
Currently, I implemented windows, boxes, and multiline entry. I have to compare this experiment with the curent implementation in terms of erformance, memory consuption etc. before to decide to continue with N-API or not.
);
}
}We're in a thread about a React Native for desktop implementation.. saying "React Native is React Native for Desktop" is confusing; hence my question.