Why desktop apps matter

Photo of Mike Hearn by Mike Hearn
November 2022

I’ve been meaning to write this essay for a while, but the recent kerfuffle over Chrome killing off JPEG XL pushed me to finally do it. This will be an argument in three parts: firstly that desktops are more important than they’re given credit for, secondly that browsers are poorly serving us on those desktops, and finally a sketch of what can concretely be done about it (which is why we built Conveyor).

I.

Throughout the 2010s there was a widespread belief in a kind of desktopocalypse, in which classical operating systems and workflows would be killed off by the then-new locked down platforms: Android, iOS and ChromeOS. In 2014 I was told matter-of-factly by a company making developer tools that nobody downloads desktop apps anymore; their plan for how to get their tooling to developers was to make an iPhone app. I asked how they’d handle devs who didn’t have an iPhone but the response was bafflement at the possibility, followed by the suggestion that maybe the company could just buy those people iPhones (a VC backed Bay Area startup, of course). In 2016 I was told by a product manager that soon nobody would use Windows, macOS or Linux anymore, because everything would be done on tablets. When WebGL was new I remember people excitedly predicting that soon games would all be delivered as web pages, even triple-A games. Pundits routinely asserted that Apple’s conversion of the Mac into a bigger iPhone was obvious and inevitable.

These predictions didn’t age well.

Apple never did turn macOS into iOS, yet here’s their quarterly Mac revenue:

That’s not a product category in decline. Mac sales remained stable throughout the 2010s despite neglect by Apple and Intel’s manufacturing problems, because there is a permanent need for general purpose productivity-oriented computing.

But in this decade growth took off again. It can’t be fully ascribed to lockdowns because revenues hit a new record even towards the end of 2022, so it’s presumably due to Apple Silicon. PC shipments are volatile but were falling until about 2016, then stabilized and turned around starting in 2017 despite Microsoft’s focus on Azure. Meanwhile Chromebooks have had a terrible few years with big declines in 2021 and 2022 despite the huge forced spike in remote schooling. The ChromeOS vision of everything being a web app failed to take off despite eye-watering levels of spend by Google; instead we saw the rise of Electron apps and ChromeOS added support for Android apps. The games industry settled decisively Steam and consoles; Google’s attempt to bring AAA gaming to the web was recently killed.

Why didn’t the desktopocalypse happen? Here’s a quick list of possibilities:

  • Keyboards and mice are still unsurpassed devices for efficiently and precisely doing work.
  • The mobile operating systems never seriously tried to compete for desk workers.
  • The locked down operating systems don’t have good support for files , which are critical for many workflows.
  • HTML/JS makes it hard to fully exploit the capabilities of the hardware, especially new hardware. It wasn’t competitive on mobile, still isn’t despite a massive effort, and things played out the same way with VR.
  • The ‘success’ of the app stores turned out to be forced, and wasn’t replicated on platforms where the stores faced competition from out-of-store distribution.

Desktops and laptops are fundamental to our world. We use them to write documents and emails, but they also power our farms, our hospitals, our factories and power stations. They are used to create movies and games, space ships, designer proteins and breakthrough AI. They run logistics and finance, they organize governments, they power our MRI machines. If every computer running a desktop OS mysteriously disappeared tomorrow, leaving behind only tablets and phones, our civilisation would collapse and weeks later we’d all be dead.

It’s safe to say neither the desktop/laptop form factor nor their operating systems are going anywhere. Apple will continue to experiment with bringing iOS code and concepts across to macOS (and vice-versa), but there are no obvious contenders to replace the big three desktop platforms.

II.

“It must be admitted that many aspects of HTML appear at first glance to be nonsensical and inconsistent.”

The HTML5 specification

JPEG XL is a new image format. It offers better image compression than JPEG and comes with a neat party trick - you can re-compress existing JPEGs to the new format without losing quality. It also has a variety of other useful features that would seem to make it a no brainer upgrade. Nonetheless, for web usage the format is now dead in the water. Chrome implemented it but never made it actually available to websites. They now plan to remove the code due to ‘lack of interest’ (perhaps caused by the inability to actually use it). Other browsers never implemented it at all.

Although this may sound crazy, it seems plausible to me that browsers are reaching some sort of tech debt or maintenance cost ceiling. Image rendering is a core function of a browser but apparently they are now “full”, and this is hardly the only feature people got their hopes up for only to be disappointed. Who will invest effort in researching new static image formats now? WASM was supposed to get support for GCd languages a long time ago, to pick just one example, and HTML has never even attempted to provide a proper table view control, even though for many types of business app this is a core need. Chrome is nearly a gigabyte of code yet it’s still not enough.

This comment on Hacker News describes the problem:

The Web platform is an abject failure of layering. It’s truly the biggest ball of mud that software has yet birthed. If it had only reasonable modularity its implementation would be large integer factors less code and it would not be necessary to wait on three browser engines to ship obscure (declarative!) features for CSS, like dropshadows, which could easily be programmed on top of a better designed, simpler core.

And don’t even get me started on “accessibility”. The web’s barely-acceptable kludges for accessibility could easily be accommodated in a layered, more programmable system.

The web platform is rife with abstraction inversion, employs declarativity where programmability is necessary, and vice versa. It puts magic in pretty much all the wrong spots. And its event-based programming model that puts all JS on the “main” (actually UI) “thread”, forcing a painful and awkward asynchronous programming model that we are gaslighting into believing is good for us, is frankly just dumb.

If argument-by-HN-comment isn’t convincing consider argument-by-expert instead: the author of that comment is Ben Titzer: WebAssembly co-founder, former V8 compiler tech lead and engineer. So I guess he would know.

This doesn’t mean the web is terrible or browsers are bad; obviously that isn’t the case. Their design gets a lot right, which is why they’re popular. Still, the starry-eyed loyalty to the web platform that was typical 10 years ago is now mostly gone. The rise of Electron is perhaps the clearest signal of browsers failing to meet the needs of what app developers and users want - reusing the core tech makes sense for hiring, feature set and other reasons, but the paradigm and constraints of the browser are tossed out.

If HTML has become so fat that even something as basic as better image formats has become impossible, what’s the alternative?

There are a few things we may observe at this point:

  • If browsers had embraced modularity and layering instead of systematically killing them off (e.g. plugins), this JPEG XL debate and many others wouldn’t be happening.
  • In theory you could use WASM and the canvas tag to implement things like new image decoders. In practice you can’t because of the overheads of repeated per-tab JIT compilation, per-site cache separation and so on. These technologies have failed to bring modularity to the web.
  • The justifications for why browsers can’t let us have nice things are usually premised on one-size-fits-all security policies that are often inappropriate.

None of these problems are going to get solved any time soon. To the extent the web has a vision it’s Chrome’s, and Chrome’s vision seems to be plumbing APIs already available to native apps through to JS and only JS, slowly or maybe not at all, with everything dumped in the giant overflowing bucket called HTML5.

III.

Any competitor to the web will probably start as a desktop app. I think this is uncontroversial. Mobile is too constrained by app store rules and browsers cannot be used to implement competitors to themselves. Also uncontroversial - nobody knows exactly what post-web technology should look like. Is it an evolution of HTML that takes it in a different direction (e.g. React Native)? Is it Rust based? Is GraalVM in the picture? Something totally new? Everyone will have different ideas.

Therefore we can break the problem down into at least two steps:

  1. Make it easy to build desktop apps.
  2. Now we can experiment with new platforms.

Traditionally many devs are reluctant to make desktop apps, even if their project really needs to. I spent years working on Bitcoin and then related projects. Again and again I saw people trying to do advanced things with peer to peer protocols or cryptography, only for their projects to sink into the waves because they were trying to do them in the browser and it just didn’t work conceptually. I’d innocently suggest they make a desktop app instead - why not with Electron? - only to be greeted with bafflement and confusion. How does one do such a thing?

Even for conventional database driven business apps there’s a world of possible simplifications available outside the browser. Web servers in such apps are mostly ad-hoc protocol translators that exist primarily to work around the browser’s constraints. Often you could as well connect directly to the database using native drivers, and skip the rats nest of issues that come with abusing HTTP as an RPC protocol (how do you best express errors or do paging for example?). It used to be that open source databases weren’t quite powerful enough to support that, but the modern ecosystem has good support for features like row level security, non-SQL stored procedures, security-invoker views and highly scalable DBaaS. With these tools you can directly connect SQL to the UI and make security fully declarative, eliminating the highly privileged web server and any SQL injection bugs by design.

In 2022 it’s also getting more interesting for mobile-first SaaS firms. Jetpack Compose Desktop lets you reuse your Android UI code for desktop apps whilst still adapting and integrating it properly. With Kotlin Multiplatform you can also share code with iOS. Many companies write their app frontend in triplicate: once for iOS, once for Android and once for the web (=desktop). With a recession well underway, reducing costs becomes a priority. Bringing the Android codebase to the desktop is an obvious way to do that.

The primary reason developers shy away from making desktop apps is distribution. Browsers download the latest version of your code, cache it and execute it regardless of platform. Getting the same results for desktop apps has historically involved a vast amount of pain. Tooling either doesn’t exist or is just wrappers around platform specific CLI programs for packaging and signing, you may not get software updates out of the box, you’ll need to setup multi-platform CI, you get flooded with a choice of numerous competing formats without any guidance on what to pick, and so on.

After years of frustration at seeing interesting ideas wither on the vine thanks to limited platforms, I decided to finally do something about it. Conveyor is the result. It’s a locally executed tool that tackles step 1 of 2 by bending over backwards to make distributing code easy outside the browser. You feed it the output of your build system - HTML/JS/etc for Electron, JARs for JVM apps or native binaries for other languages and frameworks. Then you give it a little config file to tell it where your app should download updates from, run conveyor make site and it spits out a directory of files. Upload them to the URL you specified before (maybe using the make copied-site command) and now you have a self-updating desktop app that runs on every OS, complete with a big green download button (example). Conveyor handles signing/self-signing, package creation, background updates, optimization, OS integration and all the other details for you. The goal was to make distributing and updating desktop apps as easy as compiling Markdown to a static website, and that’s a bold claim but I think we nailed it.

Conveyor will mostly be useful for ordinary standalone apps, but it could also be used for browser-like runtimes. So, what about that?

IV.

What should a hypothetical modular browser actually look like? And how can you avoid the problems that led web browsers into their current cul-de-sac? At Hydraulic we’ve started thinking about that and already have a few ideas, albeit not yet implemented.

This blog post is getting long and the topic deserves its own post, but nonetheless we think a few key bets could prove interesting:

  • Process-based/kernel sandboxes and CPU emulation are by now good enough that forcing everything through bytecode or source isn’t necessary any longer, at least not for security and portability.
  • CLIs are a core modality, not legacy. Browsers are full of useful tech that could be useful there, but none of it gets used because the web sees itself as fundamentally about drawing graphical documents.
  • Apple have shown that CPU architecture transitions can be made without forcing everyone to ship source or WASM.
  • File associations are important. For example, a Markdown ‘object’ could point at a default renderer that’s downloaded and run sandboxed, but that association could be overridable by the user. Renderers should in turn be composable/stackable, i.e. the Markdown renderer code is default associated with a “sandbox renderer” that is concerned only with sandboxing. Different sandbox renderers could implement different technologies and policies, with the job of the core runtime being to successfully communicate what policies are being implemented to the user and by whom.

These are early ideas but if you’re interested in this sort of thing, why not drop me a line (mike@hydraulic.dev) or subscribe to our blog. I’m thinking of trying to assemble a little community of people interested in post-web tech research, so if you’d like to be a part of it let me know, and if we get a critical mass I’ll send you a link to a forum.

.