Hacker News new | past | comments | ask | show | jobs | submit login
Proton Native – React Native for the desktop (js.org)
575 points by zengid on May 2, 2018 | hide | past | web | favorite | 283 comments



>You can create a GUI using something like Qt, but the code to make it is messy and unorganized.

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.)


And if we want to compare the syntax then this would be the QML equivalent:

  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')  
    }  
  }


Thank you for posting an example. I was going to.

I may be biased, but to me the QML code is much cleaner and clearer than JSX.


Something I would be curious about is what happens when you try to change the view. Like what if you want to make a counter. For me that was always the best thing about react.


I'm not sure what you're asking, but the answer to what I think you're asking is that views change by way of bindings. They can also be changed directly/procedurally, but I'll give an example of a binding.

(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.


Can you have higher order components? In react this is a function that returns a component, often taking another component as a parameter.

What's nice about react is that the JSX syntax is just sugar that converts to function calls.


> Can you have higher order components? In react this is a function that returns a component, often taking another component as a parameter.

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...


So nice not so see any < > and ( ) all over the place in addition to { }.


Tell me about it. Probably going to be down voted, but this is SO true: https://twitter.com/thomasfuchs/status/810885087214637057


Wow. Thanks for posting that, as an outsider I had no idea QT was so .. straightforward. Now I want to check it out more.


That looks beautiful. Does Qt/QML support the full power of the JS ecosystem? (bleeding edge or at least modern JS, npm)


I've used Qt developing various data-heavy apps for financial research at work and agree that making this comparison is rather inappropriate. For people who are not familiar with JSX this is not any better than the Qt syntax. This would be an alternative to Qt, but before I see a full-fledging app developed with great performance/memory metrics using this, I am not convinced enough to put it in my framework stack.


I used Qt in the early days, and always found the signal/slot model to handle events quite cumbersome. Handling events through closures (like typically done in JavaScript) is, imho, much nicer.


> I used Qt in the early days, and always found the signal/slot model to handle events quite cumbersome. Handling events through closures (like typically done in JavaScript) is, imho, much nicer.

You have been able to bind closures to events in Qt for... dunnno... 6 years maybe ?


Perhaps ironically, Javascript is a first class qt/qml citizen these days. You’ve been able to use QML with javascript—including/mainly via closures—for a while now.


I'm only an occasional Qt user but I believe since c++11 they've gained much better support for anonymous functions.


This seems like a misunderstanding of what React is. JSX is not a template. It is a DSL or superset with direct access to the presentational layer. It gets "transpiled" away in the building phase. React components are not imperative but declarative, they reflect state instead of inflating layout. Layout inflating (QT, Android), MVC/MVVM (XAML), and views being functions of state (React) are paradigm changes.

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.


There is no reason you couldn't use the example QML above in place of JSX and still receive the same benefits. It would still be `View = fn(state)`; it's just a different syntax for specifying `fn`.


From what i've seen this is layout inflating, you have a template and you fill it imperatively. Which would be one of the oldest paradigms we have. Maybe i am getting this completely wrong, forgive me in that case, but in all examples i've seen so far it's like that.

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


Here's an equivalent example for your stateful component :

  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.


And that is what i suspected and what i've seen in all examples i have browsed through so far. The enabled prop wasn't the point, it demonstrates functional composition. All of the above uses old, traditional layout inflating, dependency injection, imperative registration for re-using components, ...and common MVC. They are hard for applications that get even slightly complex.

There is a major difference between that and Reacts approach.


Sorry to go full "get off my lawn" here, but: How is this different from, say, simple GDI rendering or Swing? With both View is a function of state and rendering is done via idempotent function calls (WM_PAINT bzw. paint()/paintComponent()). This is the real traditional method. (BTW: The comparison to MVC doesn't really make sense, unless you add flux/redux/etc. to the equation.)


He means the V in MVC and while they pushed that concept for React at the beginning to help people get what it’s for... it’s not really the same at all.


.... where do you see imperative registration, layout inflating and MVC in my example ?


It just doesn't look comparable to the example i've posted. They were really, really simple, so if QT is the same, i would love to see it do the same. As for imperative registration, didn't you just link me to it? If they were functions, you could do:

    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).


> const A = () => <div>...</div> ; const B = () => <h1><A /></h1>

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
   }


Thanks for the feedback! I'm not a Qt dev, so I wasn't aware of the practices. I'll revise it and remove the Qt code.


Doesn't QT cost $459 per month per developer[1] for use in commercial applications? That price is prohibitive for anyone but established enterprise.

[1] https://www1.qt.io/buy-product/


No. In many cases, you can use Qt under the LGPL and thus for free. This is especially true when you use it via Python bindings such as PyQt.


PyQT isn't LGPL though, it only offers GPLv3 or Commercial licensing.


That's true. So using PyQt you likely need a commercial license for PyQt and not Qt. Alternatively, you can use PySide2 instead of PyQt to avoid this restriction, but it's less mature.


Less mature for the moment, but it's getting more official support and resources, so that will probably change. (They've also changed the name from PySide2 to Qt for Python.)

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."


That's good to know. Thanks for the info.


This runs on libui-node, which is a binding to the libui library.

https://github.com/parro-it/libui-node

https://github.com/andlabs/libui


Shameless plug to let you all know that there's the python bindings for libui at https://github.com/joaoventura/pylibui/ if someone wants to help on those..


That's exactly what I thought looking at the screenshots and having to look it up from the source is pretty disappointing. Libui is great work and since it seems to be the biggest part of this project, it should be mentioned.


Wow, this is the real standout here. Good find.


Nice to see this project is still alive, it shows a lot of promise but appeared abandoned for a while.

Have they got the data grid API's working yet?


Hi, libui-node author here. I'm glad for your appreciation. The project is well alive now, proton-native give me new motivational energy

The data grid has still problems on macOS unfortunately, but @andlabs is working on it...


No, the data grid has problems on Windows, as that code is being contributed by someone else. I already have it on macOS and Linux, and have for years now... Hopefully soon the Windows code will be merged in and we can keep going.


Ah yes, sorry @andlabs


Also (for the benefit of the rest of HN) s/as/but/ — I had problems on Windows, and someone is proposing a solution I just need to merge in once the mega-PR that added it and a bunch of other things are split into more manageable chunks that won't merge conflict as easily with what I am independently doing to stabilize the build.



I was actually thinking of the table view: https://github.com/andlabs/libui/issues/310 . Doesn't seem to be done yet and is critical for a lot applications.


Using Electron, you are rendering each window in Chrome, with some added OS hooks. With Proton, you are using JavaScriptCore with hooks to the native MacOS UIs and APIs.

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!


Anything that reduces the number of running chrome instances on my poor little laptop would be nice.


I tried out the example "Notepad" app in the git repo and it ran at 70MB. Is that good? I don't have any metrics about how much memory a hello world Electron app uses.


Well just for comparison, I have Notepad++ running right now with 4 medium-sized files open in it, and memory usage is still comfortably under 5 megs.


Well, that seems a bit too much. For comparison, take a look at this example electron app that I wrote to basically check if you're online using IPC.

https://i.imgur.com/g94LOvE.png

It uses around 35MB.


70MB is too much for mainly native application.

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


Fresh instance of Kate on my desktop uses 27MB, albeit its way more than a dumb text editor. Still, twice native is still in the same order of magnitude, something most naive electron apps fail to accomplish.


Another thread quoted 300MB baseline


Chrome is like the elephant that comes and sits on my laptop. Would be unusable without the great suspender.


I just declared Chrome bankruptcy and switched to Firefox a few weeks ago. CPU rarely goes over 10% on my 2017 MBP. With Chrome it was almost always above 50%.


I swapped when the new FF came out. Was sick of chrome using 3–4gb of memory and bringing my computer to a grinding vault. 3 times the number of tabs in Firefox and I have 0 issues. I recommend FF now.


I used Firefox for a couple of years for the same reason, but the new release broke my keyboard shortcuts and VimFx plugin. Now I use opera and cVim, it's even better. Much faster to start than chrome, shortcuts work, syncing works, vim works, developer tools are great, no bloated background services and square tabs!


I faced the same problem with new FF. Although not as great as Vim-Fx, saka-key does solve the problem to some extent.


Tridactyl works fine in FF. (Vim add-on)


I got a recent Great Suspender update that blew away my settings for the plugin. Did this happen to you too? It made me sad.


Yeah that got me too. Small price, although, i'm tempted to switch to firefox after reading comments here.


How have I never heard of this!? Thank you!


How do you use JavaScriptCore with proton? It runs on node which uses v8.

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.


On Windows 10, Notepad uses 2 MB and Wordpad 12 MB. I'm quite surprised that the latter can fit a full, Ribbon equiped word processor in so little memory.

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?


I recently experienced Visual Studio 6 in a Win2k VM, and it was sickening how fast it was compared to modern tools. Same with Office2k apps, and all using an order of magnitude less memory. There has to be a better way than the path we are on, software-wise.


It's ridiculous. I can launch a VM running Linux + X11 desktop environment from scratch faster than one of the most popular Electron apps launches & connects. Probably would run few apps in the VM well too with the same amount of memory.

Anything that could fix the current situation even a little bit like this project is much appreciated imho.


It starts by avoiding touching anything Electron related.

This craziness just made me buy Sublime Text.


Well, we started prioritizing code cleanliness over everything else and throwing away good tooling because it was old. Blocking performance optimizations because they're "unmaintainable," or just not thinking about resource usage, is going to result in bad software.

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.


Visual Studio Code is pretty light and extremely responsive for me on 2012 hardware


Hence why so many enterprise installs are still proudly running Office 2010.

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).


Because writing an Excel clone which is "good enough" is really, really hard work, takes a really long time and you probably won't get away with "Let's do 80% in version 1 and then optimize" - People expect Excel. Not Excel lite. Especially if they have to pay for it.


I’m not saying it’s easy, but in an age of so much disruption it’s honestly amazing how Excel continues to dominate. And I say this as someone who spends most of my waking hours in Excel...


LibreOffice was written using an overachitected component system; it is very slow. Just writing something without the layers of abstraction would be refreshing.


My mistake, it is indeed Node not JavaScriptCore, I posted a correction.


I'd love to see electron "suddenly" start reducing memory footprint as soon as a competitor starts gaining market share


Actually, earlier today Electron 2.0.0 dropped and includes an `affinity` option, which throws everything under one process. Supposed to help with memory/resource usage.


Wow, nice! Didn't think there was much room to improve given the dependency on Chrome.


According to [the PR that introduced this to Electron](https://github.com/electron/electron/pull/11501), it just takes advantage of a similar feature in Chromium.


I think it'll be hard because they depend on Chromium for performance, which is practically out of their hands and the project is already very streamlined for what it's doing. But Electron comes with a different set of tools i.e. you have the full browser API and renderer at your disposal.


Yeah, but before we say anything we should look the the performance and memory benchmarks.


Absolutely, though I can't think of a good reason why it couldn't be leagues better in performance. I'll post here with some numbers later in the day if no one beats me to it.


Correction: it's using Node, not JavaScriptCore. (I think that makes it even more useful, and it should still be far more performant)


ReactNative runs the js in plain V8 that in turn calls native apis. Native code is never generated from js at compile or runtime.


I've never heard of JavaScriptCore. I assumed that ReactNative transpiled JS to the native languages/APIs and that this would too.


The only part that's translated to native APIs is the rendering itself. Instead of rendering a WebView with an HTML <button />, it renders a UIButton from the native UIKit.

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.


Isn't it running on Node?


Thanks for pointing that out, I commented with a correction.


> You can create a GUI using something like Qt, but the code to make it is messy and unorganized. Having made a very large GUI myself, it gets very cumbersome to manage all of that.

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.


It turns out it's really hard to get a UI Builder right with HTML/CSS. In particular, layout is tricky because DOM trees imply both bottom-up and top-down constraints. For example, text getting longer pushes down content beneath it, while at the same time, the text might be 50% of it's parent node's width. The first constraint is bottom-up: the text node influences it's parent and sibling DOM node's geometry, while the second constraint is top-down.

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.


PageDraw is really interesting. I started the tutorial and when I click on the "Next ->" button, I get redirected to Google OAuth. Why is that? What am I logging into?


> In particular, layout is tricky because DOM trees imply both bottom-up and top-down constraints.

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.


NIBs in macOS/iOS are horrible for development and code review.

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.


Absolutely, most big mobile development teams I know do not use storyboards or NIBs because they are not easily human reviewable. (A small change will rearrange sections for seemlying no reason.)


I've had the exact opposite experience.

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 :)


Who reviews code for UI?

I review design screens and UI/UX workflows with end users.


Same. I wonder how anyone uses them, honestly.


Oh come on. For most parts of an application Interface Builder is just fine. Sure, for the stuff that actually matters the code is necessary because IB is not turing complete anyways.

But to arrange the view controllers and segways + some static tables it is mighty fine.


But you use live reload, no? That's just webshit for an UI editor.

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.


> No drag and drop of UI elements (aka "components"); that gets you into "absolute position" hell of Windows Forms

Only for those that never bothered to learn how to use Window Forms layouts.

https://docs.microsoft.com/en-us/dotnet/framework/winforms/c...


I think that is a uniquely iOS thing since they insist on using computer generated IDs to link objects together, while %100 human editable UI formats like HTML or Android's UI XML formats don't do that.

It's the same issue that project.pbxproj has in Xcode.


Oof. I've had nightmares about the project.pbxproj file. Such a weird design decision on Apple's part.


> We don't do it with HTML, do we? No.

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.


Agreed that NIBs are terrible, but I've found prefabs in unity to be quite pleasant.


Exactly. I feel like the design experience of HTML/CSS is the best of both worlds. You're designing in code, but it's not imperative code, which is what you have to do in iOS if you want to escape the NIB. Using declarative code to define your interface just...makes sense.


A few libraries have tried to build declarative UIs for iOS, with varying degrees of success.

This is what I love RN so much - I can build UI in 20% of the time and effort.


These are interesting points (although I don't quite follow some of your explanations). I've been trying to learn more about the history of GUI development, so I appreciate hearing about how it's been done.

Here's an interesting discussion of Delphi (2013): https://news.ycombinator.com/item?id=7613543


Sure - it was quick! Here's a short overview of how Delphi's UI design works.

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.


The downside was, that UI design was visual, Delphi used absolute positioned layout and everyone was using pixels (despite VCL supporting pt<->px).

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.


You always need the capability to generate UI in code, because static forms sometimes don't suffice. For example the layout and contents of your form depend on the data that is sent to it, like render a choice as checkbox if it is binary, use dropdown otherwise. I used delphi, etc., MFC was really bad forcing too much inheritance.


Ah, generating dynamic UI in Delphi. It worked surprisingly well, much better than many modern solutions do.


Form designers produce their own issues like compatibility between versions, poor interactions with source control and poor responsiveness.

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?


Because of productivity, and UI/UX workflows while prototyping.

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.


> Why should I spend 30 coding something away that is doable in a few seconds with a couple of mouse clicks?

Because maintainability is more important than instant gratification. If you can do both then great, but IME visual designers are a maintenance headache.


I have exactly the opposite experience regarding visual designers versus code.

Changing a couple of properties in layout files is more maintainable than hundreds of code lines just to change a visual effect.


>Changing [..] hundreds of code lines just to change a visual effect.

If you need to do that, your codebase has a serious problem.


Basic example, WPF storyboard animation defined in Microsoft Blend versus coding the full animation by hand in C#.


30 years for NIB, right? From 1988 or so?

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 pretty fascinating how tech tends to spread and influence. We spent years trying to make the web more like traditional UI dev, and now we're making traditional UI dev like web. I would never have believed this if you'd told me about it in 2010.


> and now we're making traditional UI dev like web

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.


XAML is a template, JSX is a DSL. A template kills scope, duplicates coding semantics, messes up app flow with bindings and needs dependency injection to get local scope back - all of this has been solved with JSX, which now pretty much fulfills Silverlights dream: https://news.ycombinator.com/item?id=16198843

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, ...).


XAML components ("controls" in MS terminology) contain both declarative markup and code. And it's flexible because the visual presentation can be completely overriden by the component's consumer without altering behavior, and your code can be either C# or C++.

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.


Or across multi-platforms with XULRunner from 2006 to 2015.


RIP...


Plus ça change...


Or MXML, which most certainly was influenced if not entirely derived from XAML. Everything old is new again!


I’ll put in a plug for my former employer’s OpenLaszlo, introduced in 2002 (preview) and 2003 (version 1.0).

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...


I played with OpenLaszlo way back then. It was pretty nice.


Adam Wolff, former Chief Software Architect of Open Lazlo, is now the Director of Product Infrastructure at Facebook, and oversees React and React Native.


Adam developed the initial runtime implementation of data binding and constraints — with additional help from Max Carlson, and, later, P. Tucker Withington and Henry Minsky — while I did the compiler work and language design[1][2]. Adam et al wrote the runtime constraint resolution mechanism, which initially had an API for the procedural creation of constraint graphs. I was trying to make constraints and data binding look like JavaScript expressions, that were automagically recomputed when a subexpression value changed, by extracting dependency graphs from the source and packaging them for runtime use. (All this on the Flash 5 bytecode interpreter, which was slow as the dickens, even for the time — so there was a lot of optimization: in the compiler, in the runtime, and in the interstices. Although nothing like we did later for [3].)

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/

[2] https://patents.google.com/patent/US20050038796A1/

[3] https://patents.google.com/patent/US20050114871A1/


Yeah the Silverlight vs Flex days of 2006ish really inspired this quite a bit.

Today Xamarin does all this pretty well cross platform, desktop and mobile for UWP/Mac and iOS/Android.


And TypeScript is the new ActionScript.


If you squint at JSX it also looks like JSP…


I refer to JSX as client side PHP.


I think that's unfair to PHP.


I've been using XAML at work recently (.Net 4.6) and I've got to say Microsoft did an excellent job.

The databinding approach is both elegant and familiar.

It certainly does look a lot like Vue Single File Components if you squint.


If only MSFT hadn't burned all their hacker bridges with anti-trust behavior in the 90s.


Xamarin does this pretty well cross platform as well.


Come on... That's not fair on XAML


or windows dialog RC files


UI seems to be effectively described using some sort of a markup language. HTML being the most well-understood markup language becomes a reasonable thing for stuff outside just web pages. It isnt perfect but it gets the job done. Sorta like phonegap :/


Thing is that these days HTML is a pile of div tags that CSS and JS dangle off.

Damn it, didn't we just have an article on HN about creating art using CSS?!


Indeed. A part of me is sad to see the semantic vision of XHTML lost in the mix. Though with care HTML5 can be more descriptive than its predecessors.



Writing React makes me feel more like building for web using native paradigms.


And yet there's not much that's like native GUI paradigms in React.

At least when concerning all major GUI libs.

It's more like a markup driving an immediate-mode graphics API.


You basically just described Google's Flutter framework. It's currently only mobile but I see it moving into this space at some point - or already is I guess if you count Fuschia.


You can get it working on Desktop (I've got it on Windows with the help of https://github.com/ds84182/flutter_sdl and few other hacks, but certain things are missing - there is no support for mousewheel events, docking, or more than one window. Or keyboard input (though that should be easier to add than the three listed).



Thanks! Now I have something else to play with.


Components make me think in term of OOP.


ColdFusion, Flex, XAML, JavaFX


The example in the getting started section comparing Python Qt isn't very convincing.


I tend to agree. I did years of Qt dev and I would never write something like that, nor have I seen it written like that.

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.


Not only that... but maybe its the fact that I use Qt everyday at work (C++) or that I'm not really a front end web dev, but the Python example is easier to grasp on first look.


Yeah I personally see Qt code is much cleaner.


I guess it is if you already know and like React Native?


> It is not only shorter, it is also easier to read and to edit, and can easily utilize the power of the state.

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?


Hey. I'm the author. It's hard to find a simple example that everyone understands but can show capabilities. If you're used to Qt then you're going to like Qt better, but I mainly developed this for people who want to use React. You are obviously free to use whatever you want.

But if you have any suggestions let me know!


I have zero experience with Qt, but I'm pretty sure I can follow along with the examples anyway. (I do have experience with React, JS, and Python.)

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.)


Yeah I'll reword that. My bad.


Oh, I forgot – it's probably worth considering using examples written in the same programming language as well.


Here's your Hello World in real Qt code for reference:

    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")
        }
    }


I guess just drop the comparison with Qt or other similar things. Just highlight that you can build native applications using React syntax. This alone is a good argument, no point on comparing, really. Only if you want to compare performance, etc.


The tech sounds fantastic but as you’re learning in this thread you should never criticize the competition. Framing your work as easier to read/write (or whatever) than Qt does nothing but pull yourself and the project into the mud. Just delete all references to Qt on the homepage and focus on what your project does and does well. You’ll find that approach does a much better job of communicating what you actually want to get across to people.


I think the 'easier to read' is unfair considering that you didn't use QML fur the Qt example. For me QML is easier to read than JSX (and quantitatively it is less verbose)


Is QML declarative?


As declarative as JSX

Menu {

  title:qsTr("File")

  MenuItem {

    text: qsTr("&Open")

    onTriggered: console.log("Open action triggered");

  }

}


Aren't all markup languages declarative by definition?


QML isn't only about markup, it also support property binding directly in the language - it's a full-fledged reactive environment.


Probably?


Why didn’t you address the claim that you were just straight up lying?


Because I forgot. I updated the page. My bad.


You can “skip” the whole “closing braces” stuff, then it’s definitely shorter.

I’m talking about this:

          </Button>
        </Window>
      </App>
    );
  }
}


Well, then they failed completely at their argument. I count 7 levels of indentation in the react code, when there are only 3 in the PyQt code.

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..!


No, you can’t “skip” them. If you skip them, the code is broken. The lines may well be noise, and arguably that’s even worse, but you certainly can’t skip them – counting or otherwise.


You can skip them if you want by various means, and you can also not put them on their own line. You don't even have to use JSX, which is what is taking up most of the space. A shortened, yet still totally readable (if you are used to not using JSX) version that is shorter in LOC than the Qt example might look like:

  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.


This seems like as much of a non sequitur as "skipping" syntactic elements. The comparison is clearly syntactic, and thus factually incorrect – the second example is in fact longer than the first.

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.


Here's an equivalent Qt example though, shortened like yours:

    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 !


Sort of tangential, but does anyone know of a good React Native app? Everything I've tried would clearly have been a better product if they'd just done native development. Like, you're sacrificing product quality for development ease.


You might recognize a few on this list: http://facebook.github.io/react-native/showcase.html


None of those are apps I particularly enjoy using or would want to use.


Facebook? Instagram? Airbnb? We're talking about some of the most popular apps in the world. What exactly is your problem with them?


Facebook app also has huge chunks of platform-native code, it's why they also have things like Litho: https://fblitho.com/

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?


I mean, do you realize that most of the big names on that list have a hybrid solution where they prove concepts, A/B test, and rapidly iterate-on/release new features using React Native, and then they have a native dev team for each platform that goes back and re-implements most of the core features natively?


Discord is the most impressive one to me. They definitely didn't have those resources when they wrote their iOS app[0].

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...


At that time when they released, the React Native Android was probably still in a kind of beta state.


RN Android still feels like beta.


How so? I run into the occasional hiccup an iOS and Android, but overall both have been pretty smooth for me.


That’s correct. AirBnB’s iOS app is written mostly in Swift. And Facebook’s iOS app is a piece of shit performance wise.


they are the most popular because they are needed to access a service. But they are all a fucking pain to use.


How are they a "fucking pain to use"? I have never heard an average person complain about Instagram's UI. It's fine. It's good, even.


Can you give some examples of popular apps that are not "a fucking pain to use?"


None of those are apps that I'd hold up as paragons of UI design…


yeah, the question still stands. instagram is a particularly nice example of what i'm talking about: it was much snappier pre-fb aquisition. (tho of course hard to know how much of that if any is the fault of react native or other things changing.)


Even development ease is somewhat illusionary. To be effective you will still need to know the details of iOS/Android and sometimes just write native code. At the end, why not just go full-native instead of writing and rewriting bridges.


No, you sacrifice platform specificity for better or broader functionality (given the same development capacity).

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.


Instagram uses react native, I believe


Have you heard of Facebook?


Without having used Proton Native myself, comparing your product to React Native is not something you would want to do, honestly. React Native has insanely huge growing pains, still going, even though it's been out since 2015. 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 list goes on. On the tin, React Native, and in the same way, Proton Native, look very promising, but for anything that's more complex than a demo application, my personal recommendation is to steer far away. You're free to disagree, of course, but having extensively tried to use the "write once run everywhere", my personal experience is that it always ends up more along the lines of "write once, then patch all the bugs separately on all the platforms".


I'm sorry but this seems overstated. There is already two highly competitive navigation libraries:

https://github.com/wix/react-native-navigation

https://reactnavigation.org

Edit: Replaced the word FUD with overstated, to not seem like I'm attacking the author personally.


As I stated above, it's my personal opinion on the matter. I've used both of those libraries in a medium-sized project and they don't work well. Simply linking to libraries and saying they exist is hardly making a point.


I have used both of those navigation libraries in medium sized projects as well. This is the section that struck me as overstated:

"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.


Agree with you, but think it's somewhat unfair to call the parent comment "FUD", given the specific examples cited. To me, FUDdy comments are more vague and less dis-provable. More like "but you never know whether Facebook is going to deprecate React tomorrow".

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.


Fair enough, I'll replace the word FUD with 'overstated' I do not mean to attack the author.


I looked at the GIF that the first one had on their GitHub page and it doesn't do iOS navigation right at all. I'm not impressed.


You're in pretty much every thread that pops up as a naysayer re: not using UIKit/AppKit/etc. 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.


> You're in pretty much every thread that pops up as a naysayer re: not using UIKit/AppKit/etc

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.


...mmhmm, look dude, I do iOS/macOS development as well, and I've corrected you in a few threads around here already. I'm very acutely aware of how UINavigationController works. I've worked on ports of it for React Native, and even ported it backwards to macOS.

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.


> 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.

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?


> 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.

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.


> 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.

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.


>And I disagree you with your claim that it's not noticeable.

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.


I think you are misunderstanding what this is.

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.


Yes, I'm aware of that; I've just finished up writing an treatise in reply to sibling comment that you might want to read.

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.


I had some discussion with the Wix engineer. Let's just say, they still feel the pain of going RN route. There are reasons why this may still be beneficial to them, but it is still painful.


It's not "write once run everywhere". It's "learn [React] once, write everywhere". Huge difference.


I don't totally understand why this exists to be honest. React Native for desktop is... React Native. It isn't mobile-specific in any way. In fact, it is already possible to make Windows (UWP) and macOS apps with it.

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?


> React Native for desktop is... React Native. It isn't mobile-specific in any way. In fact, it is already possible to make Windows (UWP) and macOS apps with it.

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.


If your use-case is specialist enough that you can't use UWP or WPF, I feel like maybe it's specialist enough that it might be best for you to just use the standard native tools rather than React Native?


React-Native for WPF already exists. Same repro as React Native for UWP.


> React-Native for WPF already exists.

WPF and Win32 are not the same thing.


Your original comment indicated non-UWP or Win32.


React Native seems to be geared for mobile. Proton Native uses bindings with NodeJS (via libui-node, which uses libui), which seems to be (IMO) a much better run-time for the JS part than JavaScriptCore because Node already can handle a huge amount of the OS interop. Also, JIT isn't restricted on desktop the way it is on iOS, so JSCore doesn't have a good reason to be used.


JSC is very fast, and the RN runtime is intended to be a fairly limited API, so I wouldn't necessarily say the access to the Node core packages is hugely beneficial. But it's a fair point.

I'm not sure why JIT is relevant. Neither JSC nor Node do any JITting.



In that sense, so does JSC - even on iOS. It just does so in a controlled fashion.


Can you please link to the React Native desktop projects that you're referring to?


Other than Linux support, does this offer anything more than React Native's existing macOS and Windows forks/bindings?


I've tried to improve documentation and make it ready for use. Also all the forks is are platform specific while this is cross platform.


The advantage of this over Qt is the licensing. React is an advantage if you are familiar with it over QML.

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.


The issue you linked to seems to indicate that they are going to transition to React-idiomatic naming.


Hm. Proton's are heavier that electrons...


Electron should have been named Lead or maybe Uranium.

BTW: It should be "protons" without an apostrophe.


I like react on the web, but sometimes I find it cumbersome all that sending props down and passing functions to update global state. When I'm almost done with an app and then I decide that it will be nicer to open a modal window to ask the user 2 or 3 parameters is when I miss the most the desktop paradigm of just call a method that opens a small window and returns an object with the collected data


I have a ModalContainer that passes down this.context.openModal.

https://reactjs.org/docs/context.html


The website and github README could do with a lot more examples/screenshots


Am I the only one who think that this:

    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" });


Looks nice for a short example, but later you'd also need some stuff like:

    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.


I am not saying that you don't need markup at all.

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 ?


What does your trivial wrapper actually improve though?

    window = (...children) => <App><Window>{...children}</App></Window>
App and Window are implemented in the same abstraction that the application code is written in. Not all boilerplate needs to be wrapped.


JSX is JS. While there's technically 'parsing' involved, it's fundamentally just syntactic sugar:

    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'
        ])
      ])
    ])


"JSX is JS"

It is not, https://facebook.github.io/jsx/

It is handled by transpiler - one more parsing layer in loading sequence of your application.


sounds like you have your project configured wrong, transpiling should impact compilation not the loading aspect of your application


The transpiler is a build build (a babel plugin), it isn't even a part of the application nor does it run while loading. The snippet above turns into a bunch of nested functions.


No it isn't, in the sense that it's not part of a language spec for JavaScript, like E4X (now deprecated) once was considered to become. But I guess E4X's problem was that it was too far ahead of its time and had XML in its name.

[1]: https://developer.mozilla.org/en-US/docs/Archive/Web/E4X


JSX gets transpiled, not parsed. The effort is completely on the tooling side, there's no loading effort that changes JSX into functions. The main difference between your two snippets is that one is declarative and the other is imperative. The declarative piece can reflect state and react to changes, the other can't - you do that manually.


Is this created and maintained by a single developer (kusti8?), community, or corporation?


I'm one highschooler with not enough time. Ideally this would come from someone who can maintain this full-time like a corporation, but so far no one has done it.


From my experience, you won't have more time than you do now, it's just a matter of what is a priority. Cool project.


Wow that's awesome; you really are still in highschool.. When I read your gitHub profile where it said "A sophmore at High Technology High School" I thought you were being sarcastic!


Impressive indeed :D


Very nice work man! Keep at it! =)


Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: