I joked with a group of friends the other day that I would “rather retire than teach web development”. It was an off-the-cuff comment, but there’s a grain of truth to it. Does this mean that I hate web technologies? Not at all! For many people, the internet is the world-wide web, and those technologies have directly led to our current information age. Wikipedia, YouTube, Khan Academy are all incredible contributors to our information-rich culture.
So what’s my issue? I disagree with the assumption that web technologies are somehow suitable everywhere. Businesses almost always prioritize time-to-market, monetary costs and other factors over technical priorities - that’s nothing new. What frustrates me is that somewhere along the line, mainstream developers starting buying into that compromise, resulting in a worse experience for users. Instead of looking for technologies that result in the best long-term solution, we started adopting web technologies simply for convenience. Is Javascript useful for building websites? Certainly. Desktop applications? Umm, less so. Backend services? Ok, now you’re just being lazy.
Developers used to be the voice of the business arguing in favour of technical decisions that resulted in a better product. Now? We cheerfully stuff an entire web browser engine into an executable, just so that we can continue to code everything in JS1. We stopped caring about building well-designed, crafted software in favour of software that is cheap to build. Somehow we’ve accepted that slow, non-standard applications are perfectly fine. I’m not ok with this.
Application design
The real issue is the suggestion that choice of technologies doesn’t matter, and that both paths (native vs web) are “equally valid”. Yes both paths can be used to produce something useful, and web applications are cheaper to build, but this choice has a user impact beyond deployment.
Let’s compare the user experience of a desktop application vs. a browser-based web application.
Desktop applications
Let’s think about the “native” experience (building a standalone executable for a specific platform, using conventions for that platform):
- Applications run in the context of a particular operating system, and are well-integrated into that OS. This includes things like the ability to script them, share a file system and so on.
- Interaction is handled in resizable and positionable windows, owned by the application. Tabs are possible when they make sense, but are not standard or expected in most applications.
- Applications primarily rely on point-and-click interaction, using familiar widgets and the conventions of that platform (i.e. the use of visual cues to provide meaning and so on).
- Keyboard support includes hotkeys/shortcuts. These are typically standard across the application and also the particular operating system.
Desktop design in this context is about providing users with expected, consistent behaviour. Users who know how to use one application on that platform can easily leverage skills they have developed across other applications. The application experience is specifically designed with user’s needs in-mind.
To that end, design firms and large companies like Apple and Google leverage decades of HCI and design work, and publish exhaustive human interface guidelines to ensure the best possible designs for their respective platforms.
Browser applications
A browser-based application is functionality delivered to the user through a web browser. Typically this means that the application is hosted online, and the user “opens” the application by visiting a bookmarked website.
- Applications run in the context of the browser. Behaviours depend on which browser you are running. Applications may not work on all browsers, or they may have inconsistent behaviour across different browsers.
- Interaction also happens in windows, but the windows are owned by the browser. The application does not control size and position. Applications can be split into a window, or a tab, but behaviour is often inconsistent and determines by the specific browser.
- Applications are isolated from one another, and local resources are difficult to access and manage.
- Also point-and-click for most interaction, but there are no standards in layout, widgets used. Every web application is unique, with its own interaction mechanisms.
- Keyboard shortcuts are a mix of OS-conventions implemented by the browser, browser-specific shortcuts, and application-specific shortcuts. Most of the time, applications don’t bother to implement hotkeys.
Browser applications are each unique. There are few conventions that are leveraged, and much of the behaviour is tied to the browser. For example, clicking on a link in Safari might open the link in a few tab, but on a different browser, it might replace the current page instead. By adding a second level of abstraction (web browser as application launcher) the desktop experience ends up being a confusing mix of applications and bookmarks.
Browser-based applications are also designed to be served from a web server, remotely. They also run in the context of the browser, which means that they have limited ability to interact with the underlying operating system (e.g. it’s awkward for your web app to save data locally, compared to a native application).
Why isn’t Electron a solution?
Well Jeff (I can hear you saying), why not just adopt Electron for building desktop apps? That would solve your usability issues!
Yes and no. Is the desktop experience better if you run an Electron app vs. a web based version of that same application? Yes. vscode
is better than the web-based version of that application. Neither is as consistent or performant as sublime text
, despite Microsoft pouring hundreds of millions of dollars into development.
Electron is a compromise that shouldn’t need to exist. There are native solutions that will let you build better performing, functional desktop applications now. Kotlin and Compose is one of them. Flutter and Dart would be a second. Both will get you closer to a native experience than Electron would.
Do they allow for simple, cheap cross-platform software? Not quite, but they’re getting close, and they’re a step in the right direction – trying to make cross-platform development cheaper without throwing in the towel.
So, what do you suggest?
I’m glad you asked.
It should be obvious from the rest of the content on this site that I’m a fan of the direction that Kotlin is taking towards cross-platform development.
- The
kotlinc
compiler can multiple platforms. The “standard” is to build applications and services for JDK, but native compilation support is evolving. Android is 100% native supported. Windows, macOS, and iOS support is evolving. - The challenge in building native applications is having libraries on all of those platforms. Kotlin multi-platform libraries are evolving e.g. Ktor supporting network development on any platform.
- User interfaces can be native, using native-interop between shared Kotlin application code and native libraries. As an alternative, Compose is being developed for iOS which could result in a true cross-platform UI library for iOS, Android and desktop (95%+ of the market).
- Native interop where required, to support other platform specific hardware capabilities.
I think that the direction that JetBrains and the community taking is the harder path, but it’s ultimately going to lead to better software and a better experience for users.
#kotlin #web #opinion
-
Ironically, I’m typing this in Obsidian, an Electron app. I love Obsidian, but when I publish notes, I have to use the mouse to click “ok” because standard keyboard shortcuts don’t work. ↩︎