Jeff Avery / What I Believe as an Application Developer

Created Tue, 26 Sep 2023 10:13:21 -0400 Modified Mon, 01 Jul 2024 13:11:19 -0400
458 Words

What do I believe as an application developer? What are my biases?

1. Native first

The web is an amazing platform for information sharing, and in-a-pinch, can deliver high-quality applications over a browser. The ability to instantly deliver software, without any installation or configuration from the end-user, is incredibly useful.

However, using a web application is a worse experience than a comparable native application.

  • The UI is less consistent since it’s controlled entirely by the website. Layout and style tend to be non-standard.
  • Interaction is focused on point-click e.g. keyboard shortcuts are very rare on a website, and when they do appear, are not standard.
  • Performance is often worse than native applications. Some applications cannot be delivered at-all over the web. e.g. games.
  • Inability to work with native functionality e.g. devices plugged into the computer.
  • Inability for the user to customize the experience. e.g. custom hotkeys.

For these reasons, I will usually trade the increased complexity of a native experience (harder to build, requires installation) over the simplicity of a web application (no installation). I tend to build software for more expert users, where things like UI consistency matter.

2. Cross-platform over single-platform

Native implementations provide the ability to interact with the underlying environment (see above). However, achieving this means that we often need to handle specific APIs and native integrations with all of the platforms that we want to target. macOS, Windows, Linux, iOS, Android all have different underlying APIs that require some degree of customization.

This means that we cannot simply “build native” for mobile or desktop: at some level we need custom code written for Windows, macOS, iOS and so on.

This assumes that you need these APIs. The stdlib for your language might contain sufficient functionality reimplemented on each platform, in which case, you could compile from the same source. Practically however, most applications need more than the stdlib provides.

Practically, we don’t want to reimplement our application on each platform; it’s helpful to share as much code as possible. This means designing our applications using technologies that allow easy code sharing across different platform implementations, only dipping into native implementations when absolutely necessary.

There are a couple of ways to address this:

  • strong interop support so that we can bridge shared code with native code for a specific platform e.g. shared Kotlin, but calling into a Swift UI through an Objective-C interop layer.
  • code that can execute across platforms, typically by having some common runtime implementation for each platform e.g. shared Kotlin, with a Compose Multiplatform for iOS, allowing us to build a native iOS application that bundles the Compose Runtime. Flutter also does something comparable, where your common code draws the UI on a native canvas for each platform.

#opinion #kotlin #flutter