Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Ask HN: What are the fundamental diffs between modern web vs. desktop UI models
22 points by PaulDavisThe1st on Nov 22, 2021 | hide | past | favorite | 22 comments
Roughly once a week, HN will feature a link to a new web-based UI framework/toolkit. These seem to build upon a history that, briefly stated, seems to go: HTML -> HTML5 -> JS -> Node -> React -> [ a lot of stuff ]. Obviously there are things that branched off at various points along the way.

As a purely native desktop application developer, whenever I read about these frameworks, they seem to contain almost no trace of any of the programming models/designs/lessons that were learned between (say) 1980 and 2005 in the domain of native GUI toolkits (both platform-specific and cross-platform). There's almost no trace of any of the vocabulary, but also very little sign of any of the fundamental concepts (widgets, "classic" MVC, etc.)

So I'm asking without (much) predjudice: what's so different about UI/UX in web-dev that justifies throwing away all these design lessons? Or are they really still in modern web frameworks and I'm just not seeing them?



You don’t throw those design lessons away! They are still very much in use and the standard for writing the modern web. Everything is based off the Gang of Four, and MVC has evolved to MVC-P, Model-View-Controller on the backend, with a Presentation layer on the front end. ReactJS for the presentation layer in your case. All the above, still based on the 23 Gang of Four design patterns.


I just opened my copy of Gang of Four. Almost none of the patterns there are exclusively GUI focused ... I might even go so far as to say that none of them are, but that's probably a little too strong of a claim to make.

I was really asking about the design patterns used in native/desktop GUI applications like widgets (including a wide range of widgets almost none of which seem to be offered by any/most web frameworks), anonymous callbacks/closures, explicit event loops etc.

Also, last time MVC "evolved" in a native context was, to the best of my knowledge, Microsoft's introduction of M-VM-VC where "VM" is "View Model", a slimmed down GUI-centric version of the "real" model. This way you're describing a "presentation layer" ... I don't see where the distinction between that and a traditional "View" is (or "Controller" for that matter, since in most GUI contexts, the View and Controller are frequently occupying the same pixels on a display. My guess would be that the "View" in the design you're referring to is some particular aspect of the fundamental model, rather than an actual mechanism of making the model visible to the user.


The Flux design pattern created by Facebook, and used by Redux and nearly every ReactJS app, is by definition a State Design Pattern as described in Gang of Four lol.


From the book:

"Allow an object to alter its behavior when its internal state changes. The object will appear to change its class".

You think that's somehow primarily a GUI-related pattern? Let's see what the authors say about "Motivation"

"Consider a class TCPConnection that represents a network connection. ..."

Oh, right. It has nothing to do specifically with GUI programming, but is, like more or less all the other 22 patterns, a general pattern for writing good object oriented code.

Everyone should know these patterns. It's great if ReactJS pushes people towards using this one. It doesn't have much to do with UI/UX implementation in either web or native contexts, IMO.


Oops my bad Paul, I think you are correct! I didn’t bother to look at the username before I started commenting.

But to further the convo, State isn’t a GUI related pattern. It’s the dominant design pattern used by modern JS frameworks for persisting data across the GUI.

“Consider a Redux class ProductState that represents an Axios network connection. …”


The big change is a shift towards declarative UI where the UI is a pure function of the state, avoiding mutations. That’s how React, Vue, Svelte and Flutter works for example. Very different from MFC on Windows or Gtk.


there's no ideas in native dev that arent well covered in various webdev frameworks. none. zilch.

but popular web frameworks have their own more webful lexicon/definitions.

imo few native frameworks really use the old lexicon heavily either. even in legendarily ancient realms like objective-c, there's persistient ideas, but the classic ui construction paradigms dont rule, arent the guiding star; there are still different & newer patterns & systems & words for using the available standard libraries.


> there's no ideas in native dev that arent well covered in various webdev frameworks. none. zilch.

So, I want to present a classic expanding-node treeview. In GTK, I'd use GtkTreeView, populate a data model, connect it to the treeview, and I'm basically done. A minor change of widget names, and that process covers almost any native GUI toolkit. What's the generic equivalent of that in any web framework?

Your final para feels like a restatement of my point, and I was really hoping for a justification instead.


sencha framework had all of this. a decade plus ago. tree compnents onnthe web were ultra hil, rhere were hundreds of them. this is doable modernly today too; none of it is unavailable. it's just not as popular.

i dont think any pretense that computing has very specific enduring ideas is at all ok. does iOS have any parallel constructs to you ask? i genuinely dont know but even if it does it's just not the mode.


iOS' native GUI is extremely similar to the one on macOS and is packed full of the same Cocoa-ish concepts.

They had to add multi-touch and they had to deal small screens (and reorientation), but the basic GUI concepts are essentially the same as in macOS.


The first issue here is that _nothing like `GtkTreeView` is built into JavaScript or the browser_.

Your typical classical desktop framework (Swing, Qt, wxWidgets, WinForms, Gtk) all have a huge available list of widgets with built-in behavior. That simply does not exist in a browser. You get a set of moderately capable and partially customizable form input elements, inconsistently implemented across browsers, and made worse by having a wide range of available browser versions actually in use. Beyond that, you end up having to build your own functionality out of a language that was "designed to make the monkey dance when you mouse over it", and a layout system that was originally designed to show _document_ content.

There's also been a steady shift from building "web _sites_ with a bit of interactivity", into full-blown _applications_ that just happen to live in a browser, all while dealing with a unique set of constraints. JS had no built-in module system, the standard library is beyond minimal, every page is downloaded in full and so you have to minimize bundle size, and the language is quirky. They also deal with updating a stateful persistent data model that's already built into the browser: the DOM.

So, every app is trying to simultaneously fill in a bunch of missing functionality, work across a wide variety of browsers, come up with some sort of themed appearance from scratch, and deliver all the functionality in the smallest possible byte size over the wire.

Because of all this, web apps have followed a very different evolutionary path than desktop apps.

I've covered some of this background in some slides and articles [0] [1] [2].

As for the design of the frameworks themselves: there certainly were some "classical" OOP-style widget-class-hierarchical frameworks that were out there around 2008-2010. For that matter, the GWT framework let you compile Java to JS, and had both its own built-in widget system and third-party libs like SmartGWt that provided a full desktop-like widget hierarchy. So, it's not that that's never been tried.

Those got replaced by the first wave of what were, at the time, known as "JS MVC frameworks": AngularJS, Ember, and Backbone, each of which took very different approaches to structuring data and updating the UI.

React took over from those three because it was easier to work with than AngularJS or Ember, solved the UI composition and event trigger problems of Backbone, and was far more structured than trying to update complex UI than jQuery. React itself was strongly inspired by some PHP-based patterns at Facebook.

So, it's really a very different problem space with a very different set of constraints, following a completely different evolutionary path.

[0] https://blog.isquaredsoftware.com/2016/10/presentation-moder...

[1] https://blog.isquaredsoftware.com/2019/05/presentation-js-fo...

[2] https://blog.isquaredsoftware.com/series/how-web-apps-work


> [ ... ] all have a huge available list of widgets with built-in behavior. That simply does not exist in a browser.

Right, so another way to ask my question is: Where Have All The Widgets Gone?

> So, every app is trying to simultaneously fill in a bunch of missing functionality, work across a wide variety of browsers, come up with some sort of themed appearance from scratch, and deliver all the functionality in the smallest possible byte size over the wire.

None of that really sounds particularly novel. If you roll back to the late 80s, native desktop apps were in essentially precisely the same position: missing functionality, people trying to figure out how to write apps across different platforms, themeing systems beginning to develop, all with notable performance issues if you did the wrong thing (in that case CPU cycles and memory were the constraint rather than wire size, and maybe that's enough to be the difference).

Eventually, somewhere near the end of the 90s/middle of the 2000s, most of these things were "solved" for desktop/native, or put less charitably, they stopped changing.

> Beyond that, you end up having to build your own functionality out of a language that was "designed to make the monkey dance when you mouse over it", and a layout system that was originally designed to show _document_ content.

Right, so yet another way to ask my question is: why don't web frameworks fix this by "evolving" toward a widget-like design so that web devs can think about this more like native devs?


As a developer of desktop applications as well, I've asked myself these same questions. While I don't have any definitive answers for you, I'll share my thoughts.

If you consider that an ecosystem evolves to the constraints of its environment, even from their pre-history at Xerox Parc, early GUI frameworks were incredibly constrained. But I think the most important constraint in their development was object orientation. Smalltalk blazed the trail for GUI programming, everyone else following after modeled their systems in that way. Object orientation became the most expressive way to program a hierarchical widget system (which most desktop systems are). Even early Windows HWND-style programming emulates virtual dispatch in non-object oriented C (also 'gobject').

In response, a vast body of knowledge and techniques around object orientation were amassed to mitigate these constraints as the ecosystem matured through the 80s and 90s. Not just patterns like MVC, Flyweight, Command et al, but also structural techniques like the event loop.

> Eventually, somewhere near the end of the 90s/middle of the 2000s, most of these things were "solved" for desktop/native, or put less charitably, they stopped changing.

So at the end of the 90s/middle of the 2000s the web browser grew out of being a document viewer into a very constrained widget kit, but the programming model was not object oriented and so the 'solved' problems needed to be solved again for a new set of constraints. Few of the traditional techniques applied, and the old object oriented way was either adapted (e.g. data binding became Redux, Flyweight/Prototype became templates) or disposed. Personally I find it a bit of a waste, but I don't expend any energy in the new ecosystem, so I don't want to be too judgy.

But I don't think desktop widget kits 'stopped changing', and are cherry-picking ideas from the browser, like 'declarative' (XAML, QML, etc) and 'responsive' (widget containers that re-flow the viewport for phone/tablet orientation etc). I hope I haven't misunderstood your question and wasted everyone's time.


Good thoughts, thanks for that reply.


How are you defining "widgets" in this sense, exactly? I'm not quite following what the line of questioning/thinking is here.

Like, I could say that React's "components" qualify. Self-encapsulated, reusable pieces of UI and logic, that expose a set of options for customization via props. What about libraries like React-Bootstrap, React-Widgets, Material-UI, or the dozens of other React-based prebuilt component libraries is different than the "widget" definition that you have in your head?

- https://react-bootstrap-v4.netlify.app/

- https://mui.com/

Or is the question more about the programming model and design patterns that React, Vue, and Angular are built around, and how they different from Gtk/Swing/WinForms?


A few basic widgets:

   * a treeview with expanding/collapsing nodes
   * vertical and horizontal resizable panes
   * scrollable container (i.e. contents exceed the view area)
   * spin buttons (display a value, with controls to increment/decrement)
   
that's the kind of thing I see missing from web frameworks. Are they there?


So I think the ultimate answer is that there is no standardized way to do some of these things on the web. There are many ways to accomplish UI as listed, I'll explain some here for a React app as an example.

* Tree view [0]: There is no browser level widget for this type of UI, so in a React app we would include the needed code as a dependency through NPM, and prepared for a browser with a bundler. For a tree view I think most devs would consider using a library/dependency.

* Resizable Pane [1]: Technically some resizing can be done with CSS but it's pretty superficial. I think many frontend devs would roll this themselves with some basic JS.

* Scrollable Container [2]: This is firmly in the CSS wheelhouse, and most cases will be handled by the overflow property. Some more advanced cases might use react-window [3] for a virtualized list, when you have 1000s of items.

* Spin buttons [4]: Here HTML does have us covered, as well as other basic controls like selects (drop downs), radio buttons, and checkboxes. But again if unhappy with the look you'll be reimplementing it with some light JS.

I'm a ~10yr frontend-ish web dev and have found this thread very interesting, thanks for sharing and discussing. On the web just don't have that standardized library of widgets like GTK+ or Qt, MUI is probably the closest, and that narrows you into a React app in most cases.

As for the vocabulary, a few things come to mind.

* Very low barrier to entry, just need Notepad and a browser, nothing to compile or install. One can find a beginning career without knowing much about coding logic at all. It wasn't until I moved into "modern" JS and "back of front-end" that I began to learn formal patterns and principles, and I still consider myself quite a novice in them.

* GUI exists on the barrier between design and code, so is hard to formalize and document in general. Additionally the culture of web development is slightly different, in that the expectation is every little thing can be styled and customized. This is at odds with the native approach, where a button looks like a OS button no matter what. This culture of customization/branding contributes to things like Electron where web CSS can be directly reused.

Thanks again for starting this thread, I've looked at making cross platform desktop applications before, but quickly abandoned it as it was so foreign to me. I usually opt for a small pkg'd [5] node server for my hobby application, exposing the GUI via a browser pointed to localhost.

[0] https://mui.com/components/tree-view/

[1] https://www.npmjs.com/package/react-resize-panel

[2] https://developer.mozilla.org/en-US/docs/Web/CSS/overflow\

[3] https://react-window.vercel.app/#/examples/list/fixed-size

[4] https://developer.mozilla.org/en-US/docs/Web/HTML/Element/in...

[5] https://github.com/vercel/pkg


Thanks for the detailed response.

A few additional points. First, neither GTK nor Qt really represent a particularly standardized library of widgets. They are not particularly consistent across major versions, but then in addition if you compare to some other toolkit (e.g. Cocoa/NextStep on macOS), you'll find extras and omissions no matter how you do the comparison. Moving existing code between even just major versions of any cross-platform toolkit is painful and often triggers major rewrites/refactoring that quadruple whatever the time would have been anyway. Going between toolkits (e.g. Qt <-> GTK) is essentially a complete rewrite (you retain what you learned the first time, but very few lines of code will survive). Having said, the basic structure of your code will survive, because the fundamental model of a heirarchical structure of nested widgets that trigger callbacks in response to user input (and other) events remains in place.

One critical difference with native development is that we (the developer) control the event loop. This is important enough that even Qt was smart enough to allow you use it with a foreign event loop (e.g. the one from Glib that underpins GTK). In a browser context, the actual event loop is far below your JS that you could almost pretend there's another "virtual" event loop running (and this indeed matches some React-ish docs I've read).

> This is at odds with the native approach, where a button look like a OS button no matter what

Actually, this is less and less true, especially as "office productivity" apps migrate to the cloud and what's left "native" are "creative" apps. These typically have no (or at least, less) issue with adopting look-n-feel that is wildly different from platform standards, even for something as basic as a button. Even within Apple, there is apparently a separate toolkit that they use for some/all of their creative tools (e.g. Logic Pro) which overrides a lot of the default platform theme.


This is not really an answer, but just to add fuel to the fire: There have been several attempts either to standardize a set of widgets for the web or to create a library popular enough to be a de facto standard (e.g., semantic tags in HTML 5 and JQuery Widgets). They have all failed.

My SWAG hypothesis is that, unlike native applications, web apps are as much application as they are branding opportunities. PhotoShop on the desktop has too many buttons to leave room for branding. A web application will typically leave copious real estate for branding, cross-promotion, mascots and other graphics, etc. You typically have a lot less stuff in a view/page, and that stuff usually receives more aesthetic customization and visual design attention.


> Right, so yet another way to ask my question is: why don't web frameworks fix this by "evolving" toward a widget-like design so that web devs can think about this more like native devs?

"a" widget like system presupposes one specific (not merely faintly authoritarian) vision of what fits best, what is destined to be. there's plenty of widget like systems on the web, react is little but a component/widget framework. just not with the specific design pallet imagined.

many webcomponent like systems exist, manifest across many many web frameworks & libraries. we can probably spend days trying to draw fine lines of difference between what a react component is & a wodget is but for reals, they're very shared in essence. the differences are less remarkable, clearly to me, than the similarities. and there are so many endless design systems to pick from.

backbone is a still not bad option that wprked hard to re-emact classically desktop patterns. the web got better for itself, the web kept moving & evolving. i dont think that's all progress, that the territory has proved itself yet, but it hasnt been stuck in decades old patterns. but systems lile backbone show how expressible those patterns have been.


So, HTTP servers serve up strings, parsing of the many layers of which the kernel is a webpage.

The whole thing was just supposed to be a glorified network file browser with optional index pages to explain or introduce the resources there.

The main issue seems to be folks trying to avoid the page reloading. HTTP is stateless itself, so your form submission will need to engage server code blocks that then spit back an appropriate response, “hey that username exists already” amd HTTP could care less about the content of the response, let alone it’s meaning, it’s just a string. It’s no problem if the code that responds to the form submission can render a templated response as a string and the browser gets a page and parses and displays it.

There is a no standardized means of maintaining a stateful webpage across page reloads, or even at all. It’s execution context is a remote client that is making HTTP requests and you have to wait for one and the only ways of even knowing the identity of the requester across requests, stateless protocol on purpose designed for scalability, are hacks of some kind, assuming IP addresses remain constant, or embedding à browser cookie that the browser then attaches to a future requests etc.

Remember, the payload is a string, it has to get parsed into html elements that you could call the intended widgets of the web world. The web widget creation committee (paraphrasing) effectively never got off the ground so we never got more browser native elements.

So, then you basically have everything being implemented ad hoc with Javascript and CSS, since then. React and its ilk are just ways of using JavaScript to create and append and remove elements to the tree, the DOM, dynamically without a page load. The whole thing works fine out of the box if you let the server update the state of a browsers view as was intended, but then you get a page reload, which is less than groovy if you are adjusting a virtual dial, for example.

The web being cross platform only 24-7-365, it’s been particularly vulnerable to the politics of the tech industries in a way that low level code is not. If WPF is missing a crucial widget, you can code one and build it into your product.

This is a good juncture point to bring up the incredible waste of electricity and computing power trying to create what behave like GUI applications on top of these massive virtual machines that only a handful of money pits can afford to try to build and maintain.

I would say that trust is the primary obstacle to making a truly efficient binary remote blob deployment and activation infrastructure to replace the web, even if it still just piggybacks on port 80.

IMO, the essence of the endless complication in the field of web development lies in the difference between what the web was architected to be and what we want to use it for.

I do not think it’s wise to build a universal app platform on strings. Castle made of sand.


Although I agree with many of your points, the reality is that a whole class of desktop apps - call them 'business productivity' apps - has been replaced (for better or worse) by the SaaS model of web apps (Software as a Service).

I used to believe that some types of desktop software (e.g. graphics, video editing, animation, 3D etc) could never work as web apps unless extremely limited in scope. But I was wrong.

Compare the Figma UI with Sketch. Both apps share core UI design tools.

Figma is delivered to a browser as a binary blob using Web Assembly.

Sketch is a Mac-only native desktop app with all the speed and functionality advantage of a native app. Despite that, it is 'cloud-based' Figma which is now a serious rival to Sketch. The Sketch team even wrote a blog post extolling the virtues of native apps - no doubt with a nod to their cloud rival. [1]

Sketch is also hampered by the fact that sharing designs or collaborating with others is harder than Figma. Sketch was designed in an era of single-user desktop app use, not the multi-user (cross-platform) scenario common today. This is a problem for some desktop apps.

SaaS is a juggernaut that shows no sign of slowing down and is eating the desktop model. Whether that is a good thing or not is a question for another debate.

[1] Why we’re proud to build a truly native Mac app: https://www.sketch.com/blog/2020/10/26/part-of-your-world-wh...




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

Search: