Hacker News new | past | comments | ask | show | jobs | submit login
The web as a GUI toolkit (arp242.net)
155 points by pcr910303 on Feb 13, 2020 | hide | past | favorite | 125 comments

> With the web almost everyone has a machine that has a programmable environment by default again. I feel this is a very important and powerful advantage that’s often overlooked.

As someone else who cut their teeth on an 8-bit micro back in the day, I agree with this 100%.

And I think it's a large part of the reason I'm so suspicious of the stampede in webdev toward very heavyweight toolchains over the past 5+ years; while they may have had the best of intentions, I think they do end up putting gatekeeper-ey accessibility barriers around the web's original rough democracy. It's not that the underlying technology has gone away, more that when someone starts looking around the mainstream web to see how things are put together, that's not what they're going to find.

I agree. Node, webpack, npm, babel, etc. all add a huge amount of friction to getting started. It doesn't help that they're all overly complex and every little thing has a different tool or configuration file.

It's a huge complex house of cards that nobody really wants to have to deal with. Compare it to writing a Qt app, or even something like a Flutter app. You pretty much just install an SDK and go file -> new project.

Personally I would argue that it is no more complex than JSP/JSF/Spring or ASP.NET/Web Components / Web Forms, then you have to bolt on server side session management, state transfer and the other patterns that emerge from sending everything to the server. In my opinion doing all of the UI interaction on the client is easier to reason about and simplifies state management.

Now I would tend to agree that classic ASP / PHP was conceptually simple and probably simpler than the current client side landscape, but they where beasts at scale.

I am not arguing that the current state of client side is where we want to be, but in a lot of ways it beats where we have been, and that is how we got here. It will never compete with desktop development because the web just injects a while host of complexities into the mix that you circumvent with desktop where you are delivering from the run-time up. For better or worse, the browser, the webserver and the middleware stack all dictate how we get to go about building applications for the web.

> In my opinion doing all of the UI interaction on the client is easier to reason about and simplifies state management.

Is this even true in most cases? You almost always have some state that needs to be in both places. The more you choose strategies to optimize for client-side development and treat the backend as just a store for "blobs" of data, the more problems you have given enough scale, requirements, or just the passage of time.

What you state is correct for a subset of applications, but it's not universally applicable. With enough time and experience you'll likely understand the limitations. I'm not going to keep arguing with you because your subset can get you very far, and it's probably the right thing to do for your needs.

> I am not arguing that the current state of client side is where we want to be, but in a lot of ways it beats where we have been, and that is how we got here. It will never compete with desktop development because the web just injects a while host of complexities

Can you elaborate on the complexities? The desktop (as in Win32, Qt, etc.) and the web are on different ends of a spectrum. With JavaScript frameworks we have an in-between. In many ways you can put native mobile development in the desktop bucket because they are effectively have similar constraints, although some of the ideas/tools are a more modern implementation.

When you try and build abstractions to make the web feel more and more like desktop you expose the limitations of web development. The web will support more and more application features, but progress is naturally going to be slow around the maturation of these features than if you had gone with full desktop. What's interesting is that the web keeps pace enough that it never gets eliminated from the race. This is very important part of web and why people keep betting on it.

Oh, I'm not necessarily talking about going back to old server-side stacks, more that the heavy client-side stacks seem to get used all the time even if the problem didn't need them.

If you're writing something really horrendously complicated, yes, some sort of framework will help. If it's a little throwaway tool for internal or casual use, it's usually perfectly feasible to do the whole thing in one or two hundred lines of HTML+CSS+script. No tooling, no dependencies. It's so much quicker and so much less painful, and yet bizarrely people look at you like you're a wizard because the whole thing is 5k uncompressed and doesn't even need a webserver.

"Personally I would argue that it is no more complex than JSP/JSF/Spring or ASP.NET/Web Components / Web Forms"

Both of these stacks are themselves deprecated and replaced by better solutions in the same ecosystem. "We're only as bad as 10-15 year old stacks" is hardly a compelling argument.

That sounds ridiculously more complex than clicking "new project" and just going with it.

No, I want to be clear, I certainly was not arguing that point, just making the point that I view the current state as an advancement over where we have been, in relation to past web development trends.

Or compare it to something like Lazarus, where you install the environment (sadly it is not at all portable) and can construct GUI applications with a WYSIWYG editor that compile directly to native binaries for multiple platforms.

GUI editors always go in cycles, and we always come back around to writing code as the editors can't represent the things we want to do.

Except for a huge number of use cases where they can, of course. Obviously not everything can be abstracted away, but things like Lazarus or HyperCard or even Excel offer a starting off point for people to build powerful tools to solve their problems without acquiring a traditional programming education, and offer a ramp into programming for when people need to do more with those tools.

It's still possible to get 99% of the results with 1% of the effort using something like parcel+(vue/react).

Right but part of the problem is the proliferation of different tools. If I choose Parcel I can no longer use Vue CLI, and 99% of documentation, blog posts, stackoverflow answers etc. no longer apply. Plus I have to learn what Parcel is.

This is why I've stuck so strongly with Ember for web development. Even with the modern edition of Ember, Octane, it's as simple as `ember new my-project` and off you go. No choices to make, no toolchains to configure, just writing productive code.

Qt, Flutter, JavaFX, hell even Swing is infinitely better than any JS framework. Easier to get started with. Easier to ship. Easier to maintain. Easier to do actual, you know, computer stuff with because you can do actual I/O and talk to the OS. It's not even in the same solar system as JS, from either the user's or the developer's perspective.

The state of the art in web is React which is an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Win32's UI loop.

Could have been, but I’m happy to develop in js and upload it so anybody could just visit the site and run. Build till worldwide is infinitely faster. Especially for smaller projects. e.g


This is cool but it would have been easier to build in Java or Dart or C++.

Meanwhile, I don't think any of the non-web client platforms can compete with how nice it is to develop web clients, from React to Elm to trivial async-everything + async/await + the simple Promise and concurrency management. Just to give you another viewpoint.

Sure, modern JS tooling is complex, but a 14-year-old just looking to play around with programming isn't going to build a Facebook clone as their first project. You can always create a barebones HTML file and drop some JS into a `<script>` tag and be up-and-running in two minutes. If you don't want to use modern tooling that was designed for large-scale SPAs, then don't.

I was really turned off by react because of the necessity to use JSX, which in turn required me to use babel, its just adding too much complexity. So I'm still just using jquery.

I would suggest you to take a look at Vue; you can use it without any transpiler or heavy toolchain, just adding a good ol' script tag in your headers and voilà. The getting started guide [1] is awesome and translated to a gazillion of languages, so it also helps :)

I recommand Vue to any Javascript beginner that want to add interactivity to their page without having to handle the DOM manipulation themselves.

[1]: https://vuejs.org/v2/guide/

That is what I love about it.

I hated JSX too when I started doing React 4-5 years ago. Then I used Vue for a couple of years in part because of templates.

After that I tried InfernoJS which uses JSX because I needed the performance for a project and now I've turned around on JSX.

Personally I couldn't go back to template based frameworks like Vue or Svelte because they usually put you into this one component per file mindset. I much prefer being able to create micro-components in the same file like say buttons or table rows.

The thing that annoyed the most with JSX was that writing conditionals and loops inline was ugly or a pita. Then I discovered this Babel plugin and I love it:


That plugin is the worst thing I've ever seen

I'm currently working on a project where some people had a bright idea of implementing this exact <If /> via a component instead of babel transform, so not only it looks like shit, it also breaks if you mention something that doesn't exist at this point...

Some reasoning would be nice.

I'm guessing this is mostly a nicety to paper over the fact that 'if' is not an expression in JS, so you have to do things like

    var foo;
    if (something) {
       foo = <SomeComponent.../>;
    } else {
       foo = <OtherComponent .../>;
whereas if JS has if-expressions, you'd just say

         if (something) {
         } else {
          <OtherComponent .../>;
(or similar). From that perspective it seems like a nice little thing to have.

Dart actually observed this exact thing and added if expressions inside the language; more exactly, "if" works as an expression if it is inside of an initialization of a collection. It might seem a bit less elegant that the semantics of such an important token changes with context, but I think it solves this particular problem pretty well.

Dart also has spread operators and for-expressions to make writing "UI with code" much easier. It's fresh to see how language design choices are being made more by pragmatic ones (for Dart it's the fact that it's primarily being used for Flutter to make UIs) instead of ideological ones (One might claim that "if" should be a pure expression following the tradition from functional languages like ML, but that also has its own set of problems in a language designer's perspective)


Yup, it's such a small thing, but it actually makes a huge difference. C++ has the same problem when dealing with optionals, etc. etc.

(I know absolutely nothing about Dart, but it does sound a bit weird that the expression-ness of an if is contextual. Is there a good underlying reason for the exceptionalism here?)

How come?

I'm not the person that insulted the plugin, but I had a less than positive reaction to it too. I would say that this is putting into the template what belongs as JavaScript.

In pretty much every case, where the README shows the "before transformation" and "after transformation" comparison, the "after" part is what you should be writing to begin with. This feels like adding an extra layer of abstraction just for the purpose of not learning to do some simple things in JavaScript itself.

I would be pretty annoyed if I started working on an existing React project and it had that sprinkled across all the components.

Try lit-html. You'll never look back.

If the cleanliness of their website is a hint to their usability, then this might catch on fast!

Try Choo (4kb ninja sword).

I think the design really nails it: just enough architecture, tagged template literal rendering, functional DOM tree composition with an optional component system.

I prefer to avoid stateful components in favor of pure rendering functions, as much as possible.

Choo's renderer is based on morphdom, which is interesting because it diffs against the real DOM rather than maintaining a virtual one.

I use monoapp, which is a fork of Choo allowing you to bring your own renderer (such as lit-html).



I would look into CRA (https://github.com/facebook/create-react-app). It handles all the Babel/Transpiling/Webpack mumbo-jumbo for you so you can focus on writing code.

Although I would eventually recommend learning how to utilize Babel & Webpack yourself because knowing why and how it works is useful.

If kart23's objection to complexity is how long it takes to get up and running, I agree about CRA. I agree about knowing the why of Babel and Webpack. But how they work isn't something everybody has to learn.

If it's some other objection to complexity, I'd recommend learning modern web dev using https://mithril.js.org/ which can use JSX, but in documentation the non-JSX form is primary.

I second Mithril with JSX. I've been using for a couple of months and it's amazing.

I started working on making the JSX docs a little better but got stalled... hopefully I will have some time later this month.


You might like lit-html, which has a very similar structure as JSX, but does so with standard JavaScript: https://lit-html.polymer-project.org/


    const Welcome = (props) => <h1>Hello, {props.name}</h1>;
    ReactDOM.render(<Welcome name="Taylor" />, document.getElementById('react-welcome'));

    const welcome = (name) => html`<h1>Hello, ${name}</h1>`;
    render(welcome('lit-html'), document.getElementById('lit-welcome'));

What do you get in return for losing all the react ecosystem?

Less required tooling, better performance, smaller bundle sizes, and more interoperability.

disclosure: this is your project

React is usable without JSX, which is just syntactic sugar for `React.createElement()` calls. If it's the complexity of babel/tooling that turns you off, it's also possible to use _just_ JSX without other transpilation steps: https://reactjs.org/docs/add-react-to-a-website.html#optiona....

I know I can use just JSX, but it looks really ugly, plus I have to set all the html attributes in createElement.

I guess my bigger complaint is that its all 'possible', but not recommended for production, its going to slow down your site in some way, etc. There are always drawbacks to not using the recommended way. Its like eating soup with a spork. Yeah you can do it, but its going to take you a lot longer than with the proper tool.

Not sure what you mean by necessity. I promise I’m not trying to be pedantic, but it’s not required. Plus, there are other, newer JS frameworks out there that use html templates and the like. The struggle is just maintaining valid HTML.

You don't need to use JSX, it just makes things nicer. But if your project doesn't already have enough complexity that it needs some sort of build tool, then react is probably overkill for your project anyway.

I dont use any build tool right now. You're right, I'm not building the most complicated thing in the world, but my site would definitely benefit from using react and I mostly want to switch to make future things easier, and jquery is already becoming pretty annoying.

Theres pages of content that can be sorted and filtered, so I mainly want to use it to dynamically update the elements, with the data coming from ajax calls.

I was also really turned off by JSX. It still feels like an abomination.

I love the fuck out of Vue.js/NUXT though.

unless you have to support internet explorer, modern browsers have a lot of native functions and APIs that can replace jquery easily (been hearing that for years, but last time I checked it really looked promising)

if you want to skip jsx, just write React.createElement(ComponentName, props) and your done. jsx just makes it a bit simpler to read, so no one feels tempted by horrible angular like template languages shudder

Honestly I would not shed a single tear if node.js and npm got thanos'd out of existence overnight. It is hands down the worst thing to happen to software, arguably even worse than C.

> You can always create a barebones HTML file and drop some JS into a `<script>` tag and be up-and-running in two minutes

Local "file://"? That isn't even trusted, current browsers outright block simple functionality like loading other files with XmlHttpRequest by default. You either have to completely disable various security settings or spin up a simple http server. At least I think that http is still enough for localhost, with the push for https you might want to set up a LetsEncrypt cert before you even think about starting a JS Hello World.

Not to put too fine a point on it, but is

> loading other files with XmlHttpRequest

simple functionality? To me that actually does sound kind of like an 'advanced' thing to even think of from a beginner's perspective... i.e. someone who's just trying to learn to make a web page with perhaps a little bit of interaction.

(But then, maybe my idea of a beginner's level of ambition is hopelessly old-fashioned, I don't know.)

I do think that it would be great if there were a way to tell a web browser through its Dev-thingy to actually serve a folder to itself as if it were served by a bona-fide web server with HTTPS. I mean, it's not that hard to start a python-http-module-server, or install the npm module 'http-server' (or whatever it's called), but y'know...

EDIT: I don't necessarily disagree with you, but I think it may be a matter of degree.

> I do think that it would be great if there were a way to tell a web browser through its Dev-thingy to actually serve a folder to itself as if it were served by a bona-fide web server with HTTPS.

I'd like to plug Beaker Browser as an amazing tool for getting started with barebones HTML, CSS, and JS. I would say Beaker marvelously fulfills this wish for a browser to serve a folder to itself.


Because it is built around the peer-to-peer dat:// protocol, it also ends up being "local-first" regarding web pages that you write with it (as well as sites that you decide to seed).

@staltz has an interesting presentation on the utility of Beaker Browser: https://staltz.com/beaker-frontend-dev-dream-browser/#0

On the other hand, I don't know enough to speak to Beaker's capabilities with XmlHttpRequest.

When I was a teenager learning how the web works I used the free version for MAMP for this. It was super straightforward, as I recall. Open it up, choose a folder, and serve. I think it even included PHP.

i share your frustrations, especially as a retro and nojs fan.

today, for now, it's still mostly workable, with some fiddling, and yes, setting up a local web server.

In my experience teaching 14 year olds, that is precisely the kind of thing they first want to build: the things they know and use everyday (in 2020 it’s more likely to be Snapchat/Instagram/TikTok than Facebook, but the point remains).

And indeed, with a batteries included kind of solution like PHP/MySQL, one can build a basic Facebook like in a week long workshop or so. You won’t understand everything that’s going on under the hood of course, but the fact remains that it’s way more accessible than the webpack/Babel/react.js/etc stacks that web devs push these days (waiting for the inevitable “oh no one uses webpack anymore, it’s all about ChirpChirp.js these days!” :)

Luckily you can now use standard JS modules and web components to nicely organize code and widgets without buying into any tooling or framework. Things are getting a lot better.

But then you're buying into Web Components and their limitations instead.

Luckily, whatever people could do in the pas, they can still do today, because the web is largely backwards compatible. Then at some point they'll run into some things that seem harder than they need to be, at which point they can start looking at the tooling that was designed to solve those exact problems.

do you have a sample app / repo to illustrate ? You can use repl.it to host

> With the web almost everyone has a machine that has a programmable environment by default again. I feel this is a very important and powerful advantage that’s often overlooked.

For this same reason, I’m disappointed that mobile browsers such as iOS Safari have yet to enable DevTools, e.g. a page inspector, network inspector, and JavaScript console. Especially for younger generations, there are many whose first computer will be a mobile device.

They are enabled, kind of, you need to plug the device into its bigger brother.

However, iOS more so than Android, has plenty of mature interactive code environments.

> you need to plug the device into its bigger brother

This exactly is the challenge. If your first computer is a mobile device, you would not have that “bigger brother” available.

iOS does have Swift Playgrounds [1] and Android has the excellent Termux [2] but access to the built-in JavaScript engine would open a whole new set of possibilities.

[1]: https://www.apple.com/swift/playgrounds/

[2]: https://termux.com/

I was introduced to programming on a dinky little graphing calculator. My hope is that other “first computers” could offer similar opportunities for tinkering.

Agreed, but as mentioned there are also on device coding environments.

On iOS you also have Pythonista, Continuous, Shaderific, Codea, all much better than learning FX-4500p, FX-850P Basic.

Sadly on Android, most of the alternatives are quite lacking versus the iOS variants in capabilities and quality.

Are you saying that we shouldn't have the advanced web applications that we do today?

I would say that we shouldn't have an advanced web application unless we need an advanced web application. Most of the time, we really don't need it.

You must enable JavaScript to view this static text blog.

This presumes that heavy toolchains are a prerequisite of advanced web applications. The toolchains seem to be more about ergonomics than creating new capabilities.

A large part of the toolchains are also bandaids on a lot of unnecessary friction caused by changing standards and moving targets. The web platform is almost to the point where a lot of those bandaids could just be ripped off: ES2015 modules are directly supported in most browsers today, same with CSS modules / syntax through ES2017 or more recent / and so forth, and protocol upgrades in HTTP2 and HTTP3 remove a lot of the performance-specific needs for things like bundling and minification.

The biggest hurdle to ripping off the bandaids (as with so many things in software development) is the rough edges of the long tail of legacy code. The biggest example being that there's still so much code written for CommonJS (or AMD) that needs shims to play well in ES2015 module worlds. (Because no one wants to stop the Node world and rewrite everything all at once.)

pika.dev is coming really close to shimming a ton of existing libraries into module world.

I'm not at all convinced that the heavyweight toolchains have led to any improvement in webapp quality. Maybe there are rockstar apps out there I just haven't seen, but for the most part the web these days is vastly more bloated and somewhat less stable than it used to be, without doing anything more that any user actually wants. This is not progress.

I can't think of a case in the past decade where I've really wanted to have a web application rather than a proper native thick client.

I understand the attraction, and I've had to build my fair share of them, but I don't like it at all.

Actually yes, we don't need SPAs to display basic blocks of text with some animation.

Kinda off topic, but the MSX was amazing. We had one too, it was my first computer too. I vividly recall it came with two 200-odd page printed manuals, both in my native Dutch. One for MSX-DOS, which told you how to launch a word processor and print documents.

And one for MSX-BASIC. The manual, sent to every consumer's home, taught you what variables and subroutines were. It had pictures of jars with $A printed on the outside that you could put a 5 in and the later put a 6 in. In Dutch! In my home! I was 10. I was learning programming but I didn't know I was - I thought I was just learning the computer.

Years later my parents got me a "programming with superlogo" book and only then I discovered that I already knew how to program. That was pretty odd. <3 MSX and whichever Philips exec decided that consumers needed programming language manuals.

> I was learning programming but I didn't know I was - I thought I was just learning the computer

Back then these were not really separate concepts. Frankly, I don't think they should be nearly as separate concepts today either but nearly everyone making software seems to disagree.

One thing I hope will come out of a more code literate society (looks like a lot of high schools are teaching it now) is that, all software will be written assuming every user knows at least some scripting.

Often I clone a piece of software because I want to change just one thing, or even if it's open source I often need to set up a build environment etc... and I just wanna change like one integer!

> all software will be written assuming every user knows at least some scripting.

I don't know if that's what the answer is. I prefer the idea that computer usage naturally flows into computer programming. Take the most used programming environment in the world: Microsoft Excel. It can be used very simply as a table of words and numbers, but if you want to do more with it there are formulas, and when you reach the limit of that there's VBA. We used to have tools like HyperCard that allowed people to build simple GUI applications with no traditional programming language whatsoever, but also had one baked in for when you grew beyond the WYSIWYG editor's capabilities. That sort of thing basically no longer exists, and to the extent it does it is merely a copy of what existed before instead of an evolution.

> Often I clone a piece of software because I want to change just one thing, or even if it's open source I often need to set up a build environment etc... and I just wanna change like one integer!

Yeah, it'd be really great if more software was written with flexibility in mind. I want to have an API for interfacing with everything, I want to setup my own custom hotkeys, etc. I can kind of get there today with things like AutoHotKey, old Macs had AppleScript, Plan9... existed, but it is kind of ridiculous that this sort of thing isn't baked in to modern computing.

> Back then these were not really separate concepts.

That was not my impression. It did also ship with MSX-DOS, which very much wasn't a way to program the system. And, sure, BASIC let you launch programs and manage files, but it was cumbersome at best.

It's as if you get a Chromebook and it contains two manuals: one for Chrome ("how to open a web page") and one for the Devtools ("Chapter 1. HTTP")

> I vividly recall it came with two 200-odd page printed manuals, both in my native Dutch. One for MSX-DOS, which told you how to launch a word processor and print documents.

Ya, I still have that one :-) I ditched almost all my belongings a few years ago when I moved to New Zealand, but the MSX-BASIC book is one of the few non-essential things I kept :-)

This seems a good starting point for a complex yet possibly constructive tool-related discussion.

I recently started building a bunch of personal productivity and hobby apps using Lazarus / Free Pascal, because there are quite a few things I didn't want to deal with from the web development world:

- Constant browser upgrades that can instantly change how well your JS tools work, especially if you integrate third-party components like CKEditor

- The sheer number of different types of updates that are spread across various front- and back-end contexts: HTML, CSS, JS, and PHP/More JS/whatever, but then you've also got to consider your choice of editor / coding environment, whether you're using SASS, any deployment tools, fonts and font services, etc.

- Having a single binary to use vs. needing to open a web browser which will then try to tie everything together for you, meanwhile maybe you have good reason not to be using a web browser at all

- Working with tons of files that exist locally, and will always exist locally, and which you don't want to add to a server or the cloud (doable via the web tools but just a bit weird in its way)

It's been nice to just build a thing I need and see it immediately fit into normal native desktop app characteristics, meanwhile I can focus on the productive logic and workflow. But that doesn't really even sum it up, does it? You can do _something like that_ on the web...it's just different.

I found myself with ample time to design an icon for my latest desktop app, having completed all the main functions, and caught myself smiling at the thought--it was a good feeling.

Decades ago I discovered HTA (Html Applications). It was a program from MS that let you build applications using a single html file. It had no browser UI in it, had it's own button in the menu bar, and other than the default white background it looked like a native application. All you needed to update it was to edit the file and reload the application, no compilation step needed. You could embed scripts and styles and even images so it could be one file if you wanted. I used it for building small toy apps. It was the times of IE5, I didn't really care about browser upgrades. Better of all, the files were small and you didn't need to package an executable since all Windows machines had the executable already.

Does Lazarus have a good GUI story on MacOS yet?

Good, no, but there is a working one. The Carbon backend is still the best "native" option, though thanks to Catalina that isn't really an option anymore. The Cocoa backend has issues, but nowadays gets all the effort so things will improve faster than previously (but you most likely want to check the development versions).

The most stable and featureful backend is most likely Qt though, largely because it is also used by people on Linux. There aren't that many Mac developers after all (and Apple doesn't make it exactly easy for them).

In any case, macOS will always be a sort of "third wheel" for Lazarus since it is the most "alien" to the way it works. After all the API was designed (by the Delphi developers) for Windows and it feels most comfortable in Windows-like environments.

Of course IMO even that is much better than a web-based environment which doesn't feel comfortable anywhere :-P

I'm end-to-end Linux here and migrating all our Macs to Linux so I'm not sure. The dev team seems responsive enough that I'd make sure you're using the very latest version you can get, and maybe the situation has changed since whenever you tried it last.

I am extremely negative on HTML/CSS as a ui framework. Yet like many, I have been paid well to come over to the dark side of Javascript app development. The opening section in this article is one of the first times I've agreed with some positive view on the benefits of the environment. Zoom really is a cool feature that is not easily possible in more traditional GUI frameworks.

I also have to begrudgingly admit that nowadays I can mostly create really nice interfaces with very little effort. This is thanks to browsers finally reaching an acceptable level of compatibility (anyone remember Acid CSS test), Javascript/Typescript evolving with genuine improvements (e.g. async/await), flex layouts (and soon grid!). There is still huge room for improvement but it isn't anywhere near as bad as it once was.

I'm so on the opposite side of this opinion.

To my view, the better tech aligned with the problem domain, the better off are developers and end users. Using typesetting format for rich UI apps is so far from what UI toolkits need and has created enormous amount of pain, losses and security vulnerabilities. Making it the only available option on the dominant software platform (web) made it the worst cataclysm in the UI software industry.

Like, in a slightly different turn of events, it could be Lotus or Excel spreadsheets format as a GUI framework. You can easily imagine how XLS becomes the dominant monopoly in UI toolkits and evolve chaotically to accommodate web demand for UI features. After decades of evolution and billions of lines of XLS and VB scripts, one could easily find "some things that work very well" with spreadsheets as a GUI toolkit approach. It doesn't make it a good fit, though.

Why would anyone think that using text markup language for UI apps can be a good idea?

If to speak about browser technology as a GUI toolkit then there are three big things that are greatly underestimated.

1. Bubbling/Sinking(Capturing) event propagation schema.

With that schema a container knows what event is passed to a child and did child process it or not. On desktop, windowed widget handles all its events without notifying/asking its container.

This actually is pretty big - it enables composition of atomic input widgets. On Web you can use <input|text> as part of more complex widget.

2. CSS and CSS selectors in particular.

As the way of styling component from outside - independently from its event handlers/code.

So code changes DOM state and CSS defines how that state shall be presented. And not only that but styling of elements in context (cascading).

That is "separation of concerns" at its best.

3. And the DOM.

While each UI system has DOM ( tree of windows/widgets ) in one form or another the Web pushes its further: it adds unification of widget (attributes/states) interface.

Any widget or element may have ID, class or other attributes defined. And those can be used for styling.

GUI toolkits certainly allow for containers to act on events before their children. For example sendEvent: and hitTest: in Cocoa.

The web's event handling is comparatively clumsy. It is cast in terms of "listeners" which are unable to directly control the event routing. Instead it exposes fixed, ad-hoc levers: stopPropagation, stopImmediatePropagation, preventDefault, etc. And because there's no good place to put these methods, they have to go on the event itself, which means that events are mutable (!).

"sendEvent: and hitTest: in Cocoa"

That is cooperative event propagation. Means it works only when widget cooperates by itself - designed to be embeddable and expandable - so it notifies its container about events inside.

Example: try to catch right mouse button click on NSButton instance. Good luck with this.


I wouldn't say so. I am doing UIs professionally quite a long time and can prove that WWW's Event/Sinking event propagation + ability to subscribe to event by JS closures is the most flexible schema so far. It is a functional superset of events handling architectures of Windows and any toolkit there, MacOS/Cocoa, GTK and QT.

In practice CSS rarely lives up to the aeparation between state and presentation. In most projects the to are updated in tandem. DOM is not expressive enough to represent state, it moreso represents UI state, but CSS also represents UI state.

That is more about architecture actually.

Ideally Web/UI component has two sets of styles: So called "primordial" or "base" - the one that defines layout of sub-components and parts and that is essential for component operation.

And another set is about decoration - colors, fonts, sizes.

For example in Sciter (https://sciter.com) component is defined by so called style sets:

    @set nullable-input-base {
      :root { flow:horizontal; }
      :root > input { display:block; width:*; }
      :root > button.clear { display:block; }

    // concrete nullable-input styling:
    // derives from nullable-input-base
    @set nullable-input < nullable-input-base {
      :root { background-color: var(inputback) }
      :root > button.clear { 
        background: url(x-cross.svg) 50% 50% no-repeat;
And in script:

    class NullableInput : Reactor.Component {
       const styleset = ["nullable-input", url("widgets.css") ];

       function render() {
         return <widget.nullable-input>
            <input|text />
            <button.clear />

This way you can redefine nullable-input in the way you want without putting any styles into code.

Some GUI toolkits have adopted these patterns.

In JavaFX events bubble/capture in the same way as on the web.

JavaFX has CSS which styles its equivalent of the DOM (the scene graph). User defined components can extend CSS if they want.

JavaFX nodes can all be styled with style/styleClass attributes. But the JavaFX DOM is superior to the web DOM: it has layout management nodes, every property is observable and bindable in a unified manner, and there's a more principled approach to handling collections.

Everything that you can do in JavaFX you can do in WWW platform too and with surprisingly small set of features.

> every property is observable and bindable in a unified manner

Yep, see: https://developer.mozilla.org/en-US/docs/Web/API/MutationObs...

In Sciter I went even further, in CSS there you can define

    widget { 
      prototype: MyWidget url(widgets/mine.tis);
    widget[mode="editable"] { 
      prototype: MyEditableWidget url(widgets/mine.tis);
and so to have dynamic subclassing of the same DOM element: depending on attribute value the same DOM subtree element may have different classes - controllers. Good luck with that in Java.

Easy, because in Java I have the complete graphics stack at my control, so I can extend the nodes programmatically and even ensure that hardware accelerated rendering takes indeed place without Z layer tricks and hope for the best.

While with CSS, when was Houdini supposed to be available actually?

Why would you do that rather than just bind the editable property to something though? I don't actually see CSS the language as anything to be especially proud of, although the borders/box/cascade design can be useful.

Great that the DOM API got this basic thing at some point. Now how do you define observable properties on non-DOM objects? The whole thing is just a pile of special case hacks really.

Ctrl+F ability is so understated. I often use mobile sites rather than their respective apps precisely so I can Ctrl+F to find what I'm looking for on the page quickly

To be honest, many apps are nothing more than a crippled browser showing you a website.

Also: https://xkcd.com/1174/

I had a similar experience in my youth (just replace the MSX with a C64). The author is right when he says that programming a PC (either in DOS or Windows) was non obvious; but once you realized that the best way was to use a spreadsheet or a database engine, you could get a lot done quite easily. Those tools may not be as generic as Python or Perl, but you could program whole applications in a fraction of the time.

As for the web, I think it is still harder than it could be, and the browsers make it more difficult every day, since they put more and more restrictions when opening a local page.

There's kind of a big bump in using HTML/CSS/JS. It's easy to slap together some simple stuff, or fiddle with a web page, but you'll hit a certain point where you want your app to do something useful. Suddenly you'll be stuck reading about webservers, databases, Electron, and whatever else.

In some ways it's still easier to make a basic Java Swing application. You can just install Java and start working through tutorials.

the great thing about the web is universality. no one controls the platform yet. although, that could change, as browser engines consolidate. The web, also allows you to be OS agnostic. most of my work is done via the browser. with the only native programs I run being a media player eg vlc or smplayer since linux doesn't handle gpu video decoding and some terminal windows. with tools like Figma etc. Web programs are here to stay and win. Though we suffer a regression in usability with people who abuse tools like React etc

Building a browser GUI is simple. I would even argue extremely trivial. Here is a video demo of one I built in the not too distant past (github link at the end): http://mailmarkup.org/sharefile/demo1.mp4

It took me a little more than 2 weeks to write and test the GUI in that video. From this experience I have learned the following:

* If you are comfortable working with the DOM and vanilla JS you should be spending more effort writing the content and services that populates the GUI rather than the GUI itself. I would say this ratio of time should be something like 20% GUI and 80% content starting out and scaling towards greater content effort as the requirements upon the GUI increase.

* A JavaScript based GUI can be extremely fast and responsive. The video demo was captured on a 4k resolution and it performs, at least to human interaction speed, just as responsively as the OS's GUI even in VMs. That high resolution also explains why the video text is hard to read on a small mobile device. I intentionally wrote this to be fast though using vanilla JS and the standard imperative DOM methods, because that is the fastest way to execute things in the browser. It stands to reason if you go about things in a much slower way it will likely perform slower, possibly slow enough that the user notices a huge difference.

* A JavaScript GUI can be extremely lightweight with tiny code. This is only true if you are comfortable working with the DOM without a bunch of code decoration and abstraction nonsense.

* If the code is organized well it will scale well even in the face of numerous competing enhancements. I solved the problem of scale with TypeScript interfaces and constant refactoring.

* There is one aspect that does not scale well, which any feature that requires complex algebra. One example is dragging a highlight rectangle over some elements for a mass selection and ensuring that highlight rectangle is confined to the containing element and that it knows which elements of the parent element are visually occupying the same space and which ones aren't. Another example is that the CSS property text-overflow only works if dimensions are statically available to the current element or its parent node. That means calculating a dimension for an element in order to set the value upon the element, which requires some calculation written by you instead of relying upon something like display:block;width:auto.

* All presentation, and I do mean absolutely everything except dynamically modified display, opacity, position, and specified dimensions should be in CSS. The presentation that is not in CSS is directly on the DOM node by dynamically reassigning new presentation values on user interaction where necessary. This allows for smaller and more scalable code.

* All icons are Unicode characters. The only one other graphic, because the desktop background, is an SVG spinner. SVG, being XML, can be adjusted with CSS just like the rest of the DOM.

Got some links where I can read more about this?

And check this: https://flightjs.github.io/

Funny thing is these three points:

- Copy/paste anything.

- Search any text with e.g. Ctrl+F.

- Back button.

Tend to disappear with javascript frameworks, single page applications, ajax, and websites partially or fully rendered with canvas

Web is very inferior to any modestly well done UI toolkit.

As someone who spent most of his time in the last 20 years building web application and only recently (2 years) started using gui toolkits (mostly QT but also wxwindows), I certainly can relate to this. What a breath of fresh air... consistent UI, no fiddling with half-assed components or soon-to-disappear frameworks, no time wasted reinventing the wheel, excellent performance, no markup/code dichotomy... Great results with ease, I wish I made the jump earlier.

I mostly write stuff for others, and they do what they want with it. Or for GitHub.

But my own stuff only goes on Tor onion sites. So it's strict HTML, because Tor's latency punishes client-server dialog. And also because people will hate on you for scripts.

Also, I thought that this might be about WebGUIs. Such as the pfSense WebGUI, which still amazes me in its depth and usability. Or indeed, that you can route the WebGUI of a remote pfSense VM as a Tor onion service, and manage it just as easily as the box in the closet.

yup it is :) fossil ui - runs the browser as UI (from https://www.fossil-scm.org/home/doc/trunk/www/index.wiki)

one of the first examples I've seen, but not the only one.

Agree with all the pros stated in the article. However, there are cons:

1. Each desktop app is shipping almost a full browser, updating it independently and bloating RAM, storage and CPU utilization in the process.

2. RAM/CPU bloat issues are real - even the V8 team advices against overreliance on excess RAM. They've noticed a speed increase in the process of releasing V8-lite aimed at aggressive gc

3. Even amongst the most mature GUI frameworks based on html/js, there's far too much overhead for trivial things, like reading/writing to file. For instance, in electron, since the browser V8 context isn't allowed willy-nilly storage access, a file read from the browser V8 goes across a couple IPC requests to complete. Also, these hops aren't widely documented and understood, making desktop apps janky by default, instead of fast by default

As I understand it, the author isn't even talking about web based GUI toolkits like Electron but more about the web itself (i.e. CTRL-F, back button, etc).

> Each desktop app is shipping almost a full browser

Unless you use the OS included web view.

We used this approach in a project last year and we went from about 100MB for an Electron macOS app to 4MB. Memory consumption also went down drastically although I don't remember concrete numbers.

> RAM/CPU bloat issues are real

If you only use the web view for the GUI it should be pretty lean.

> there's far too much overhead for trivial things

You can easily solve the IPC problem by using a local web server and making requests from your web view. Also, the IPC overhead is only a problem in intensive use cases many of which can be mitigated by moving logic away from the web view and into your native layer.

> If you only use the web view for the GUI it should be pretty lean.

That only keeps your binary size lean. It doesn't help at all for your RAM/CPU usage issues.

So far nobody has made a lean web view in terms of RAM & CPU/GPU usage that can also handle modern JavaScript & CSS. It just doesn't exist currently.

> Also, the IPC overhead is only a problem in intensive use cases many of which can be mitigated by moving logic away from the web view and into your native layer.

That requires you to have a native layer at which point why bother with the limitations & complexities of a web view instead of just using QT, GTK, Swing, etc...?

> It doesn't help at all for your RAM/CPU usage issues.

Well, it does, because most likely the system webview is already loaded on ram. The problem of electron is that every single electron app uses a different instance of Chrome — webviews are shared, and unless you have no browsers/apps with webviews running, it can just share the memory already loaded.

Only the binary is shared and not even all of it. And it's not at all the dominate usage of RAM anyway.

See all the memes about chrome and ram usage - and that's all shared across tabs!

You don't need to run stuff in Electron. I usually use stuff like Spotify and Slack in Firefox, which works well enough.

And yeah, the web isn't perfect. As mentioned in the article I just wanted to highlight some of the good things here. It's not intended to be a comprehensive overview of all the pros and cons.

I wonder what would happen if all major OS & Browser vendors decided to agreed on a long-term plan to migrate/evolve the HTML, CSS, and JS specs & implementations towards a functional equivalent variation that could be efficiently implemented with the same semantics and level of security (or better) but with far less CPU and memory inefficiency, removing indirection and dynamic abstraction layer by layer, until suddenly we get something that has all the legitimate benefits of modern web development, but with the same memory/CPU footprint of Cocoa or .NET, being also cross-platform and built into every OS. Wouldn't that be great?

Before that can happen, we'll get WebASM + WebGL interfaces (efficiently) in our browser. I expect an explosion of alternate layout mechanisms to arise from that. They won't be very good at first, but they may end up somewhere neat.

> I expect an explosion of alternate layout mechanisms.

No need WebASM for that. Just one CSS property:

    div {
      flow: custom [funcname/url(of-layoout-controller)];
+ single function funcname() that will replace children and report min/max intrinsic sizes.

Wait, is this real? What's it called, so I can google it?

Building on top of WebGL would mean completely custom renderers that have to reimplement everything else too, such as scrolling and context menus and text selection. This has been tried dozens and dozens of times by big players, and never works out.

What we need to do custom layout in browsers properly without the need to give up all the nice builtins like font rendering and scrolling and a11y, is simply the ability to measure text properly.

I'd be happy if they just stopped cramming more stuff into HTML CSS and JS and just worked on optimisation from here on in. That way we could let our computers catch up.

Lets call it done.

I feel like this is unrelated to the post, which was not talking about electron apps and was instead talking about the text-based origins of the web, and why that's good.

1 is only an issue for electron. Not viewing web apps in your web browser.

Note they talk about the web, not HTML/CSS (and many of their pro arguments do not apply to Electron by default, so it's clearly not included)

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