There's this old mantra that Cool URIs don't change that Tim Berners Lee has been championing since 1998. And in the subtitle of the linked document it says:
What makes a cool URI?
A cool URI is one which does not change.
What sorts of URI change? URIs don't change: people change them.
And that's exactly what happened in my case: I changed them. Tim goes on later in the document:
Pretty much the only good reason for a document to disappear from the Web is that the company which owned the domain name went out of business or can no longer afford to keep the server running.
That latter part ("or can no longer afford to keep the server running") was me—a person, not a company—in my late, money-saving student days. At the time, I owned tomayac.de, and after making the switch to tomayac.com, I let go the .de domain after a while because I didn't want to pay for it anymore.
While I did make sure to redirect everything properly (that is, using a permanent 301 redirect), the problem really was that I had referenced the .de domain in my printed Master's thesis that I couldn't change and in which I wrote about a tool I built called REST Describe & Compile. And of course over the years I had accrued the occasional external link that I likewise couldn't control.
I think the .de domain was parked for a while gathering dust, until it was taken over by André Nowak who redirected it to a page on his site called Tomayac.de – REST Describe & Compile Tool. Many years passed…
For some nostalgic reason a couple of days ago, I decided to see if I could get my domain back. So I emailed André out of the blue based on the imprint of linux-abos.de and asked him how much it would cost to transfer tomayac.de back to me, and what happened next is just the nicest story.
André kindly offered to sell it back to me for a back link and the price he originally payed for the domain, that is 12€, plus 1€ for his tax advisor, since, turns out, domains are fixed assets. Before I even had a chance to pay him, he sent me the auth code. I ended up sending him 25€ as a thank you after successfully moving the domain to Google Domains.
Now all that remains is setting up DNS properly, get a certificate, set up an .htaccess, and all these things I'm not really good at and never know if I'm looking at the cached version from the DNS server or the live one, but I'll figure it out eventually and make all those cool URIs work again!
There's this old mantra that Cool URIs don't change that Tim Berners Lee has been championing since 1998. And in the subtitle of the linked document it says:
What makes a cool URI?
A cool URI is one which does not change.
What sorts of URI change? URIs don't change: people change them.
And that's exactly what happened in my case: I changed them. Tim goes on later in the document:
Pretty much the only good reason for a document to disappear from the Web is that the company which owned the domain name went out of business or can no longer afford to keep the server running.
That latter part ("or can no longer afford to keep the server running") was me—a person, not a company—in my late, money-saving student days. At the time, I owned tomayac.de, and after making the switch to tomayac.com, I let go the .de domain after a while because I didn't want to pay for it anymore.
While I did make sure to redirect everything properly (that is, using a permanent 301 redirect), the problem really was that I had referenced the .de domain in my printed Master's thesis that I couldn't change and in which I wrote about a tool I built called REST Describe & Compile. And of course over the years I had accrued the occasional external link that I likewise couldn't control.
I think the .de domain was parked for a while gathering dust, until it was taken over by André Nowak who redirected it to a page on his site called Tomayac.de – REST Describe & Compile Tool. Many years passed…
For some nostalgic reason a couple of days ago, I decided to see if I could get my domain back. So I emailed André out of the blue based on the imprint of linux-abos.de and asked him how much it would cost to transfer tomayac.de back to me, and what happened next is just the nicest story.
André kindly offered to sell it back to me for a back link and the price he originally payed for the domain, that is 12€, plus 1€ for his tax advisor, since, turns out, domains are fixed assets. Before I even had a chance to pay him, he sent me the auth code. I ended up sending him 25€ as a thank you after successfully moving the domain to Google Domains.
Now all that remains is setting up DNS properly, get a certificate, set up an .htaccess, and all these things I'm not really good at and never know if I'm looking at the cached version from the DNS server or the live one, but I'll figure it out eventually and make all those cool URIs work again!
The other day, I came across Elk Native, a native version of the rather excellent, if early-stage, Mastodon Web client Elk. To be honest, I wondered why they would build a native version, if the Web client works so well. I downloaded the 7.8 MB Elk_0.4.0_macos_x86_64.dmg and immediately ran into Issue #74, that is, a blank screen.
To better understand the motivation behind the Elk Native developers, I tried the same for one of my apps, with different frameworks. This repository contains the same PWA, SVGcode, wrapped five times with different cross platform software frameworks.
SVGcode is included as a git submodule in each framework folder. To run the apps, you first need to build SVGcode, and then start the wrapper app. In each subfolder, run the following commands.
⚠️ I'm a Web developer, not a desktop app developer. I simply followed the "Getting started" guides and may well be holding the frameworks wrong.
While I managed to get all apps to run, none of them worked perfectly out of the box, and there was always a strange error I could not explain. SVGcode works fine on Chrome, Safari, and Firefox when run in the standalone browsers. To see what's under the hood of the frameworks, I looked at the user agent data via DevTools.
// If `navigator.userAgentData` is available, use it. copy(JSON.stringify(await navigator.userAgentData.getHighEntropyValues([ "architecture", "bitness", "model", "platformVersion", "uaFullVersion", "fullVersionList", ]),null,2));
// Else use the user agent. copy(navigator.userAgent);
I started looking into building the apps, but didn't get too far. Electron.js looks like it has the most developed toolchain, but when I ran electron-forge make, I ended up with a 332,1 MB executable called svgcode-electron.app that only showed a white screen, despite the electron-forge start development app working mostly fine.
To build the apps, run the following command in each subfolder. (So far I have only worked on Electron.js.)
npm run build
I didn't even look into the signing part, which is required for proper distribution.
I'm not sure what to make of this. To be honest, I didn't see anything that would be more compelling than just browsing to svgco.de, clicking Install, and be good. But then I obviously didn't tap into any of the native features that cross platform frameworks allow you to do. I only noticed how features that I get for free in the Web version, like Window Controls Overlay or File Handling were broken. But again, I may just be holding these frameworks wrong. For now, it was a worthwhile exercise, but I think I'll stick to the Web.
I'm a big fan of the macOS
Continuity Camera feature, which
lets me use the camera system of my iPhone (11 Pro Max) as a webcam in macOS,
since the built-in FaceTime HD camera on my MacBook Pro (13-inch, M1, 2020) is,
well, not the greatest.
It used to work just fine everywhere in the past, but at some point it stopped
working in Chrome. It would still find the camera in native apps like
PhotoBooth, FaceTime, etc., but not in the browser. As I'm also a Ventura beta
tester and always on the latest betas, I blamed a bug there. Turns out, this is
a new-ish privacy feature and working as intended. Redditor
bonnerup filed feedback (FB11639588)
about the problem with Apple, and got the following response (sic):
Due to privacy concern with unintended camera selection, browser based video
apps only see the phone when it is in "magic pose" of landscape, screen off,
locked, motionless (not handheld), and unobstructed camera. This pose is also
used to trigger Automatic Camera Selection in supporting applications such as
FaceTime and Photo Booth.
Since this is not documented anywhere apart from a
Reddit post,
I thought I'd share it here as well. Once I put my phone in the "magic pose", it
worked just fine.
My iPhone model doesn't support all video effects yet, but
Center Stage works and
is pretty cool. It makes it look like if the camera would move and follow me. I
also use
Voice Isolation,
which helps in noisy environments.
If you want to build an app, you have several ways of doing it. You can build a
platform-specific app for the platforms you care about, for example, Windows,
Android, and iOS. In which case you would build three apps. You can also build a
(progressive) Web app, possibly in addition to platform-specific apps.
Alternatively, you can choose a cross-platform framework such as
Electron.js or
Ionic that promises to let you write once and run
anywhere. Let me begin by walking you through three extraordinary examples of
apps whose makers chose to also build for the Web, apart from building
platform-specific apps.
Beacon cases that demonstrate the Web's abilities 🔗
I always saw Photoshop as one of the last bastions of high quality apps that
supposedly would never make it to the Web platform. Forget that—this last
bastion has finally fallen. With Photoshop,
Adobe, together with Chromium engineering, has managed to get a beta version of
Photoshop running in the browser that can serve as the new beacon showcase of
what is possible on the Web. In it, you can try out the commenting workflow and
test some early Photoshop editing features Adobe is piloting on the Web. You and
your collaborators can now open and view Photoshop cloud documents in the
browser, provide feedback, and make basic edits. All in one place without having
to download or launch the app.
Similarly, Microsoft has launched
Visual Studio Code on the Web,
a fully fledged, installable Web experience of its integrated development
environment (IDE) that makes developing completely in the browser possible,
including the option to open and edit files on the local file system.
Lastly Twitter—whose progressive Web app (PWA) is
largely seen
as probably the best mainstream Progressive Web App—has
used
its responsive Web codebase for all platforms, mobile and desktop, via Web
browsers. On Windows, the PWA is the experience the company is confident enough
to make the Twitter experience that you get when you
install
the app from the Microsoft Store.
Twitter in the Microsoft Store
Linkability and universality: the Web's super powers 🔗
All three companies, Adobe, Microsoft, and Twitter, in parallel with their Web
apps, have well-established, platform-specific Windows, macOS, Android, iOS, and
Linux versions of their apps Photoshop, Visual Studio Code, and Twitter
respectively. So why did they build for the Web on top? The answer lies in its
linkability and universality.
As Google's Thomas Nattestad
put it:
"The simple power of a URL is that anyone can click it and instantly access it.
All you need is a browser. There is no need to install an application or worry
about what operating system you are running on".
According to
Microsoft's Chris Dias, with Visual Studio Code
for the Web, when working with GitHub "you can make quick edits, review PRs,
and continue on to a local clone". The sole fact that you can share a link to
your work unlocks collaboration patterns that users have embraced and loved
since the birth of apps such as Google Docs. Twitter, of course, lives and dies
by its links. News sites regularly
link to newsworthy tweets,
which means "keeping it quick"is core
to ensuring people can get from an article straight into the app, where they can
read or engage with the linked tweet.
Web applications are inherently universal. They run on whatever operating system
is capable of running a Web browser and they do not need to be compiled for each
operating system separately. The same code base powers the application on all
platforms. This does not mean that there are no compatibility issues—there are
plenty actually—but there is a
solid, shared, increasing baseline that all
applications can build upon.
While more ubiquitous on mobile, linking into a platform-specific app from the
Web on desktop is comparatively rare. On mobile (and macOS), this works via a
technology called
Universal Links on iOS (and
on macOS), and App Links on
Android. Platform-specific apps alternatively can rely on
registered protocol schemes
such as itms-apps: for when you want to deep-link into the App Store app on
macOS or iOS, or register your own custom schemes for your own apps. So while
technically possible, linking into platform-specific apps is a lot less flexible
and requires more plumbing work than simply linking into a Web app.
The slow decline of interest in cross-platform app frameworks and the rise of Flutter 🔗
The Web isn't the only platform that promises "write once, run anywhere".
Cross-platform frameworks à la Electron.js do, too. With the Web becoming
powerful enough to drive apps such as Photoshop that were thought to be
impossible, we can, however, observe a slow decline of interest in
cross-platform desktop app frameworks such as
Electron.js and NW.js, and
mobile app frameworks such as Cordova or
React Native; while at the same time there is an
undeniable increase of interest in Flutter.
The following
Google Trends chart
shows the five frameworks side by side. While noting that this chart does show
disambiguated topic trends as detected by Google (as opposed to ambiguous
search term trends),
nevertheless it is clearly not an exact science.
Google Trends interest over time for Electron, NW.js, Apache Cordova, Flutter, and React Native.
[Source]
StackOverflow statistics
on tag usage also support this. The underlying assumption of people actually
using a technology correlating with people asking questions about that
technology on StackOverflow is not beyond the realms of possibility.
Shouldn't everybody be building for the Web, then? 🔗
Given the examples of Photoshop, VS Code, and Twitter, that show that it is
indeed possible to build amazing applications on the Web, and given the Web's
super powers of linkability and universality, two research questions come up:
Web applications still lack certain functionalities that platform-specific apps
have. In the following paragraph, I list representative examples of such
functionalities on different platforms.
First, it is impossible, even with an installed PWA, to obey the macOS user
interface paradigm of having the
app menu at the top of the screen.
It can easily be achieved with frameworks such as Electron.js via the
Menu class. (On
the Web, the next best thing is
Window Controls Overlay; getting
support for app menus is tracked as crbug/1295253.)
Another example is in-app purchases on macOS that can be handled via Electron's
inAppPurchase()
method. (On the Web, the next best thing is the
Digital Goods API,
currently limited to Android and ChromeOS.) Installers are a common way users
have learned to install applications on Windows. With Electron.js, it is
possible to create
installers
and make installed applications
update automatically.
(On the Web, Web Bundles are the next best
alternative in Chrome.) This list is not exhaustive, and Electron.js is
mentioned as a representative apps framework out of several.
How big a challenge is this?
There are undeniably a number of capabilities that are missing from the Web. In
many cases, they are "nice-to-have", but not necessarily required for a still
great experience. Carefully assess if a capability can be seen as a progressive
enhancement. For an example of this approach, check out the article
Progressively enhance your Progressive Web App.
Collectively, we have educated users to look for apps in app stores. Some stores
such as the
Windows Store and
the
Android Play Store
have started to embrace (wrapped!) PWAs (optionally
limited to ChromeOS),
and offer graphical user interface tools like
PWABuilder (internally based on the command line
tool bubblewrap) for
submitting applications. Meanwhile, on other stores such as Apple's App Store,
the situation is different and less welcoming, and apps
may or may not
make it into the App Store, depending on the outcome of the app review.
Recently, Oculus, a division of Meta Platforms that produces virtual reality
headsets, has announced that PWAs would be accepted into the
Oculus Store.
How big a challenge is this?
If your users are on one of the platforms whose stores accept PWAs, you can
publish your app to the stores in question. Remember linkability as one of the
Web's super powers. Your app is discoverable, advertisable, and linkable from
the Web, too. Investing in a memorable domain name can sometimes actually be
better for discoverability. Even for app stores, people still rely most on
recommendations from friends and family members to discover new apps according
to
research done by Google.
Apart from making apps themselves available for a fee, apps can also be
monetized by selling items as in-app purchases (for example, items in a game
app), or by selling subscriptions (for example, regular courses in a fitness
app). If the developer integrates with payment providers, all of this is
available to Web apps as well, but the smooth integration of stores and their
related payment systems make this a lot more attractive for platform-specific
apps, albeit at a 15–30% commission. For apps built using
Trusted Web Activities
and delivered through the Google Play Store, developers can now use the
Payment Request API
and the new
Digital Goods API
to integrate with Google Play Billing.
How big a challenge is this?
When you profit from the convenience of app store billing or in-app purchases,
at the same time you also leave a part of your benefits on the table as a
commission. As a matter of fact, some apps that are published to app
stores even ask their users to make the purchase off-store. One well-known
example is
Netflix with their external subscriptions.
From personal experience through talking to many of Google's partners, a lot of
companies struggle with hiring great Web developers.
The talent shortage is real, and recruiting costs are high, which is why
startups commonly hire in-house recruiters who often approach recruiting with a
breadth-first approach that has not helped the reputation of recruiters with IT
professionals. Also, companies often already employ teams of Android and/or iOS
developers that they cannot just retrain to become Web developers. Creating a
PWA requires a high level of specialization that not all Web developers can
offer.
How big a challenge is this?
In the current economic situation, hiring any kind of developer is
difficult. Hiring someone with Web development skills is, in comparison to other
platform-specific coding skills, still easier
according to StackOverflow surveys,
which (in part) also explains the popularity of app frameworks such as React
Native, Ionic, Flutter, and others that are based on Web technologies.
Existing apps legacy (and migrating the user base) 🔗
It is not unusual for companies to have made massive investments in
platform-specific apps, and giving up these investments, as well as a user base
acquired over time (not to speak of the vanity install statistics), is not easy.
Apparently, starting from scratch, even when a company has an existing website,
appears very unattractive in comparison, but sometimes it does
happen.
How big a challenge is this?
Vanity is vanity, but once you have set up new, potentially more meaningful,
tracking metrics than number of app installs such as
increase of indicators of
purchase intent, you can start tracking those instead.
Web compatibility is still the
main issue
mentioned in developer surveys like Mozilla's, but also in internal surveys that
Google has run. Having to support specific browsers, avoiding or removing a
feature that doesn't work across browsers, or making a design look or work the
same across browsers are frequently brought up as challenges. Projects such as
webcompat.com collect user-submitted browser bugs and
invite interested developers to fix them. Mozilla operates a
repository with
interventions and patches to enable individual sites to run successfully in
Firefox. WebKit maintains a
quirks list
and
hires WebKit Web Compatibility Analysts.
How big a challenge is this?
Compatibility is the top priority for Web developers and browser vendors alike.
With feature testing and progressive enhancement, impressive apps which behave
well on all browsers can be built. For an example of this approach, check out
the article
Progressively enhance your Progressive Web App.
As well as browser compatibility, Mozilla's
2020 developer survey
likewise showed that developers struggle with tools and frameworks. Supporting
multiple frameworks in the same code base, understanding and implementing
security measures, plus outdated or inaccurate documentation for frameworks and
libraries, and keeping up with the large number of new and existing tools or
frameworks were all cited.
How big a challenge is this?
The tooling and framework situation in the Web development world is infamous for
being confusing and hard to keep up with. In practice, though, companies would
use one technology and tooling stack and stay true to it for many years. The
world of tech Twitter is one thing, the reality in businesses, where the
decades-old jQuery is still (and by a large amount) the
most
popular framework, is the other.
Security (or rather, the theater of security with certificate pinning) 🔗
In platform-specific app development, certificate pinning restricts which
certificates are considered valid for a particular app. Instead of allowing any
trusted certificate to be used, developers pin the certificate authority issuer,
public keys, or even end-entity certificates of their choice. Clients connecting
to that server will treat all other certificates as invalid and refuse to make
an HTTPS connection. The hope is that this renders "person-in-the-middle"
attacks impossible, so platform-specific apps are more "secure" than Web apps,
where traffic can easily be sniffed with browser DevTools. There are ways to
circumvent pinned certificates
on all platforms, so it is mostly the theater of security at this point.
How big a challenge is this?
As outlined
earlier,
certificate pinning mostly just increases the effort an attacker has to put into
sniffing your traffic and reverse-engineering the functioning of your app; but
it doesn't make it impossible.
Web applications have seen impressive performance improvements thanks to
advanced technologies such as WebAssembly (including
SIMD),
WebGPU, and general JavaScript engine
progress in recent years. Nonetheless, a carefully developed, platform-specific
app will typically outperform a Web-based application (albeit the situations
where this actually matters may be limited). With even high-performance
audio-editing tools like Soundtrap (thanks to the
Web Audio API and
AudioWorklet),
interactive development environments like
Jupyter Notebook, and graphics-editing tools like
Figma (thanks to WebAssembly), and of course
graphics-intensive games like Quake (thanks to
WebGL and
WebGPU in the future), the boundaries are
being pushed at a rapid rate.
How big a challenge is this?
There are two types of performance problems: those where truly every frame
counts, as in gaming or WebXR experiences, and those where apps feel "janky", or
unreliable. For the latter, new APIs such as the
View Transitions API
can help. For the former, WebGPU is probably the most promising API on the
horizon. Very rarely, but admittedly sometimes, a device may just be too slow to
render a given experience, which clearly happens with native apps, too, where
developers can specify
minimum required device capabilities.
For research question ②, one possible explanation is
that it is a
Google-backed
toolkit for "building beautiful, natively compiled applications for mobile,
Web, desktop, and embedded devices from a single codebase". If even Google, as
the maker of Android, trusts Flutter enough to build some of its strategic apps
with it, such as
Stadia
(RIP) and Google Ads for both Android and iOS,
and
Assistant apps on
smart display embedded devices, that is quite a signal to send. Also note how
Web and desktop are included in Flutter's output options, which means Flutter is
no longer limited to just mobile (with submission into app stores as the
carrot), and the promise is that it reduces the development cost of apps by the
number of targeted platforms. (Prominent target platform omissions so far are
Apple CarPlay, WearOS, WatchOS, and tvOS.)
An argument that is frequently brought up for Flutter is
hot reloading. On the
backend, Flutter also
plays well with Firebase,
so apps are easy to scale. Important for Web, and as Flutter was initially
criticized for rendering everything inaccessibly onto a <canvas>, the
framework now has
two different Web renderers
it can automatically choose from:
HTML renderer: This renderer uses a combination of HTML elements, CSS,
canvas elements, and SVG elements, and has a smaller download size.
CanvasKit renderer: This renderer is fully consistent with Flutter mobile
and desktop, has faster performance with higher widget density, but adds about
2 MB in download size.
By default, Flutter selects the HTML renderer when the app is running in a
mobile browser, and the CanvasKit renderer when the app is running in a desktop
browser.
Flutter relies on
a library of pre-made widgets
called Cupertino (for the iOS-native look) and Material (for the Android-native
look) that allow developers to quickly develop a good-looking application with a
shared code base. It is worth noting that Flutter-built user interfaces are
platform-agnostic because Flutter’s Skia rendering engine
does not require any platform-specific UI components. (A downside of this
approach of wrapping everything the app needs instead of reusing platform
primitives directly is app size.)
Apps in Flutter are developed in Dart, an object-oriented programming language
that supports both just-in-time (JIT) and ahead-of-time (AOT) compilation.
Flutter compiles directly to native ARM or Intel x64 code, which has a lot of
performance advantages. Dart is also easy to pick up for developers coming from
any other object-oriented programming language.
Flutter’s documentation is generally recognized as
best in class and its cookbook application
makes getting started with a baseline scaffolding a simple copy and paste job.
The Flutter community is thriving and it's easy to find help if you are stuck.
Dash, the mascot for the Dart language and the Flutter framework.
It is undeniable that amazing apps can be built on the Web. Photoshop, VS Code,
and Twitter are the stand-out examples in this article, but there are many
others. One of the Web's super powers is its linkability, which is hard to beat
on platforms other than the Web. There seems to be a certain tendency for
cross-platform app frameworks to become less attractive to developers, with the
notable exception of Flutter, which allows for Web as one of its target
platforms. Reasons for not building for the Web are easy to find, but it is
also not hard to find counter-arguments to take these reasons apart. Some of
them rely on outdated or weak assumptions, for example, PWAs not being welcome
on app stores, or platform-specific apps being more secure than PWAs. Others are
things that are in process, like closing the app gap by adding missing Web
platform APIs. Some reasons apply equally to both worlds, for example, for
hiring to be a challenge. I could go on, but in the end it all boils down to the
concrete circumstances your use case needs to be built for. In this article, I
have given a number of really strong arguments for building for the Web, while
also not hiding the fact that the Web is a platform that is still not perfect,
and pointing out that other alternatives exist. And as the three stand-out
examples have shown, the decision is also not mutually exclusive. You can build
a powerful Web app, and have a great, platform-specific application at the same
time. It is up to you to decide if you want to. And as I said in the title:
"Not everyone's currently building for the Web, but probably more people
should". In my humble opinion.
If you want to build an app, you have several ways of doing it. You can build a
platform-specific app for the platforms you care about, for example, Windows,
Android, and iOS. In which case you would build three apps. You can also build a
(progressive) Web app, possibly in addition to platform-specific apps.
Alternatively, you can choose a cross-platform framework such as
Electron.js or
Ionic that promises to let you write once and run
anywhere. Let me begin by walking you through three extraordinary examples of
apps whose makers chose to also build for the Web, apart from building
platform-specific apps.
Beacon cases that demonstrate the Web's abilities 🔗
I always saw Photoshop as one of the last bastions of high quality apps that
supposedly would never make it to the Web platform. Forget that—this last
bastion has finally fallen. With Photoshop,
Adobe, together with Chromium engineering, has managed to get a beta version of
Photoshop running in the browser that can serve as the new beacon showcase of
what is possible on the Web. In it, you can try out the commenting workflow and
test some early Photoshop editing features Adobe is piloting on the Web. You and
your collaborators can now open and view Photoshop cloud documents in the
browser, provide feedback, and make basic edits. All in one place without having
to download or launch the app.
Similarly, Microsoft has launched
Visual Studio Code on the Web,
a fully fledged, installable Web experience of its integrated development
environment (IDE) that makes developing completely in the browser possible,
including the option to open and edit files on the local file system.
Lastly Twitter—whose progressive Web app (PWA) is
largely seen
as probably the best mainstream Progressive Web App—has
used
its responsive Web codebase for all platforms, mobile and desktop, via Web
browsers. On Windows, the PWA is the experience the company is confident enough
to make the Twitter experience that you get when you
install
the app from the Microsoft Store.
Twitter in the Microsoft Store
Linkability and universality: the Web's super powers 🔗
All three companies, Adobe, Microsoft, and Twitter, in parallel with their Web
apps, have well-established, platform-specific Windows, macOS, Android, iOS, and
Linux versions of their apps Photoshop, Visual Studio Code, and Twitter
respectively. So why did they build for the Web on top? The answer lies in its
linkability and universality.
As Google's Thomas Nattestad
put it:
"The simple power of a URL is that anyone can click it and instantly access it.
All you need is a browser. There is no need to install an application or worry
about what operating system you are running on".
According to
Microsoft's Chris Dias, with Visual Studio Code
for the Web, when working with GitHub "you can make quick edits, review PRs,
and continue on to a local clone". The sole fact that you can share a link to
your work unlocks collaboration patterns that users have embraced and loved
since the birth of apps such as Google Docs. Twitter, of course, lives and dies
by its links. News sites regularly
link to newsworthy tweets,
which means "keeping it quick"is core
to ensuring people can get from an article straight into the app, where they can
read or engage with the linked tweet.
Web applications are inherently universal. They run on whatever operating system
is capable of running a Web browser and they do not need to be compiled for each
operating system separately. The same code base powers the application on all
platforms. This does not mean that there are no compatibility issues—there are
plenty actually—but there is a
solid, shared, increasing baseline that all
applications can build upon.
While more ubiquitous on mobile, linking into a platform-specific app from the
Web on desktop is comparatively rare. On mobile (and macOS), this works via a
technology called
Universal Links on iOS (and
on macOS), and App Links on
Android. Platform-specific apps alternatively can rely on
registered protocol schemes
such as itms-apps: for when you want to deep-link into the App Store app on
macOS or iOS, or register your own custom schemes for your own apps. So while
technically possible, linking into platform-specific apps is a lot less flexible
and requires more plumbing work than simply linking into a Web app.
The slow decline of interest in cross-platform app frameworks and the rise of Flutter 🔗
The Web isn't the only platform that promises "write once, run anywhere".
Cross-platform frameworks à la Electron.js do, too. With the Web becoming
powerful enough to drive apps such as Photoshop that were thought to be
impossible, we can, however, observe a slow decline of interest in
cross-platform desktop app frameworks such as
Electron.js and NW.js, and
mobile app frameworks such as Cordova or
React Native; while at the same time there is an
undeniable increase of interest in Flutter.
The following
Google Trends chart
shows the five frameworks side by side. While noting that this chart does show
disambiguated topic trends as detected by Google (as opposed to ambiguous
search term trends),
nevertheless it is clearly not an exact science.
Google Trends interest over time for Electron, NW.js, Apache Cordova, Flutter, and React Native.
[Source]
StackOverflow statistics
on tag usage also support this. The underlying assumption of people actually
using a technology correlating with people asking questions about that
technology on StackOverflow is not beyond the realms of possibility.
Shouldn't everybody be building for the Web, then? 🔗
Given the examples of Photoshop, VS Code, and Twitter, that show that it is
indeed possible to build amazing applications on the Web, and given the Web's
super powers of linkability and universality, two research questions come up:
Web applications still lack certain functionalities that platform-specific apps
have. In the following paragraph, I list representative examples of such
functionalities on different platforms.
First, it is impossible, even with an installed PWA, to obey the macOS user
interface paradigm of having the
app menu at the top of the screen.
It can easily be achieved with frameworks such as Electron.js via the
Menu class. (On
the Web, the next best thing is
Window Controls Overlay; getting
support for app menus is tracked as crbug/1295253.)
Another example is in-app purchases on macOS that can be handled via Electron's
inAppPurchase()
method. (On the Web, the next best thing is the
Digital Goods API,
currently limited to Android and ChromeOS.) Installers are a common way users
have learned to install applications on Windows. With Electron.js, it is
possible to create
installers
and make installed applications
update automatically.
(On the Web, Web Bundles are the next best
alternative in Chrome.) This list is not exhaustive, and Electron.js is
mentioned as a representative apps framework out of several.
How big a challenge is this?
There are undeniably a number of capabilities that are missing from the Web. In
many cases, they are "nice-to-have", but not necessarily required for a still
great experience. Carefully assess if a capability can be seen as a progressive
enhancement. For an example of this approach, check out the article
Progressively enhance your Progressive Web App.
Collectively, we have educated users to look for apps in app stores. Some stores
such as the
Windows Store and
the
Android Play Store
have started to embrace (wrapped!) PWAs (optionally
limited to ChromeOS),
and offer graphical user interface tools like
PWABuilder (internally based on the command line
tool bubblewrap) for
submitting applications. Meanwhile, on other stores such as Apple's App Store,
the situation is different and less welcoming, and apps
may or may not
make it into the App Store, depending on the outcome of the app review.
Recently, Oculus, a division of Meta Platforms that produces virtual reality
headsets, has announced that PWAs would be accepted into the
Oculus Store.
How big a challenge is this?
If your users are on one of the platforms whose stores accept PWAs, you can
publish your app to the stores in question. Remember linkability as one of the
Web's super powers. Your app is discoverable, advertisable, and linkable from
the Web, too. Investing in a memorable domain name can sometimes actually be
better for discoverability. Even for app stores, people still rely most on
recommendations from friends and family members to discover new apps according
to
research done by Google.
Apart from making apps themselves available for a fee, apps can also be
monetized by selling items as in-app purchases (for example, items in a game
app), or by selling subscriptions (for example, regular courses in a fitness
app). If the developer integrates with payment providers, all of this is
available to Web apps as well, but the smooth integration of stores and their
related payment systems make this a lot more attractive for platform-specific
apps, albeit at a 15–30% commission. For apps built using
Trusted Web Activities
and delivered through the Google Play Store, developers can now use the
Payment Request API
and the new
Digital Goods API
to integrate with Google Play Billing.
How big a challenge is this?
When you profit from the convenience of app store billing or in-app purchases,
at the same time you also leave a part of your benefits on the table as a
commission. As a matter of fact, some apps that are published to app
stores even ask their users to make the purchase off-store. One well-known
example is
Netflix with their external subscriptions.
From personal experience through talking to many of Google's partners, a lot of
companies struggle with hiring great Web developers.
The talent shortage is real, and recruiting costs are high, which is why
startups commonly hire in-house recruiters who often approach recruiting with a
breadth-first approach that has not helped the reputation of recruiters with IT
professionals. Also, companies often already employ teams of Android and/or iOS
developers that they cannot just retrain to become Web developers. Creating a
PWA requires a high level of specialization that not all Web developers can
offer.
How big a challenge is this?
In the current economic situation, hiring any kind of developer is
difficult. Hiring someone with Web development skills is, in comparison to other
platform-specific coding skills, still easier
according to StackOverflow surveys,
which (in part) also explains the popularity of app frameworks such as React
Native, Ionic, Flutter, and others that are based on Web technologies.
Existing apps legacy (and migrating the user base) 🔗
It is not unusual for companies to have made massive investments in
platform-specific apps, and giving up these investments, as well as a user base
acquired over time (not to speak of the vanity install statistics), is not easy.
Apparently, starting from scratch, even when a company has an existing website,
appears very unattractive in comparison, but sometimes it does
happen.
How big a challenge is this?
Vanity is vanity, but once you have set up new, potentially more meaningful,
tracking metrics than number of app installs such as
increase of indicators of
purchase intent, you can start tracking those instead.
Web compatibility is still the
main issue
mentioned in developer surveys like Mozilla's, but also in internal surveys that
Google has run. Having to support specific browsers, avoiding or removing a
feature that doesn't work across browsers, or making a design look or work the
same across browsers are frequently brought up as challenges. Projects such as
webcompat.com collect user-submitted browser bugs and
invite interested developers to fix them. Mozilla operates a
repository with
interventions and patches to enable individual sites to run successfully in
Firefox. WebKit maintains a
quirks list
and
hires WebKit Web Compatibility Analysts.
How big a challenge is this?
Compatibility is the top priority for Web developers and browser vendors alike.
With feature testing and progressive enhancement, impressive apps which behave
well on all browsers can be built. For an example of this approach, check out
the article
Progressively enhance your Progressive Web App.
As well as browser compatibility, Mozilla's
2020 developer survey
likewise showed that developers struggle with tools and frameworks. Supporting
multiple frameworks in the same code base, understanding and implementing
security measures, plus outdated or inaccurate documentation for frameworks and
libraries, and keeping up with the large number of new and existing tools or
frameworks were all cited.
How big a challenge is this?
The tooling and framework situation in the Web development world is infamous for
being confusing and hard to keep up with. In practice, though, companies would
use one technology and tooling stack and stay true to it for many years. The
world of tech Twitter is one thing, the reality in businesses, where the
decades-old jQuery is still (and by a large amount) the
most
popular framework, is the other.
Security (or rather, the theater of security with certificate pinning) 🔗
In platform-specific app development, certificate pinning restricts which
certificates are considered valid for a particular app. Instead of allowing any
trusted certificate to be used, developers pin the certificate authority issuer,
public keys, or even end-entity certificates of their choice. Clients connecting
to that server will treat all other certificates as invalid and refuse to make
an HTTPS connection. The hope is that this renders "person-in-the-middle"
attacks impossible, so platform-specific apps are more "secure" than Web apps,
where traffic can easily be sniffed with browser DevTools. There are ways to
circumvent pinned certificates
on all platforms, so it is mostly the theater of security at this point.
How big a challenge is this?
As outlined
earlier,
certificate pinning mostly just increases the effort an attacker has to put into
sniffing your traffic and reverse-engineering the functioning of your app; but
it doesn't make it impossible.
Web applications have seen impressive performance improvements thanks to
advanced technologies such as WebAssembly (including
SIMD),
WebGPU, and general JavaScript engine
progress in recent years. Nonetheless, a carefully developed, platform-specific
app will typically outperform a Web-based application (albeit the situations
where this actually matters may be limited). With even high-performance
audio-editing tools like Soundtrap (thanks to the
Web Audio API and
AudioWorklet),
interactive development environments like
Jupyter Notebook, and graphics-editing tools like
Figma (thanks to WebAssembly), and of course
graphics-intensive games like Quake (thanks to
WebGL and
WebGPU in the future), the boundaries are
being pushed at a rapid rate.
How big a challenge is this?
There are two types of performance problems: those where truly every frame
counts, as in gaming or WebXR experiences, and those where apps feel "janky", or
unreliable. For the latter, new APIs such as the
View Transitions API
can help. For the former, WebGPU is probably the most promising API on the
horizon. Very rarely, but admittedly sometimes, a device may just be too slow to
render a given experience, which clearly happens with native apps, too, where
developers can specify
minimum required device capabilities.
For research question ②, one possible explanation is
that it is a
Google-backed
toolkit for "building beautiful, natively compiled applications for mobile,
Web, desktop, and embedded devices from a single codebase". If even Google, as
the maker of Android, trusts Flutter enough to build some of its strategic apps
with it, such as
Stadia
(RIP) and Google Ads for both Android and iOS,
and
Assistant apps on
smart display embedded devices, that is quite a signal to send. Also note how
Web and desktop are included in Flutter's output options, which means Flutter is
no longer limited to just mobile (with submission into app stores as the
carrot), and the promise is that it reduces the development cost of apps by the
number of targeted platforms. (Prominent target platform omissions so far are
Apple CarPlay, WearOS, WatchOS, and tvOS.)
An argument that is frequently brought up for Flutter is
hot reloading. On the
backend, Flutter also
plays well with Firebase,
so apps are easy to scale. Important for Web, and as Flutter was initially
criticized for rendering everything inaccessibly onto a <canvas>, the
framework now has
two different Web renderers
it can automatically choose from:
HTML renderer: This renderer uses a combination of HTML elements, CSS,
canvas elements, and SVG elements, and has a smaller download size.
CanvasKit renderer: This renderer is fully consistent with Flutter mobile
and desktop, has faster performance with higher widget density, but adds about
2 MB in download size.
By default, Flutter selects the HTML renderer when the app is running in a
mobile browser, and the CanvasKit renderer when the app is running in a desktop
browser.
Flutter relies on
a library of pre-made widgets
called Cupertino (for the iOS-native look) and Material (for the Android-native
look) that allow developers to quickly develop a good-looking application with a
shared code base. It is worth noting that Flutter-built user interfaces are
platform-agnostic because Flutter’s Skia rendering engine
does not require any platform-specific UI components. (A downside of this
approach of wrapping everything the app needs instead of reusing platform
primitives directly is app size.)
Apps in Flutter are developed in Dart, an object-oriented programming language
that supports both just-in-time (JIT) and ahead-of-time (AOT) compilation.
Flutter compiles directly to native ARM or Intel x64 code, which has a lot of
performance advantages. Dart is also easy to pick up for developers coming from
any other object-oriented programming language.
Flutter’s documentation is generally recognized as
best in class and its cookbook application
makes getting started with a baseline scaffolding a simple copy and paste job.
The Flutter community is thriving and it's easy to find help if you are stuck.
Dash, the mascot for the Dart language and the Flutter framework.
It is undeniable that amazing apps can be built on the Web. Photoshop, VS Code,
and Twitter are the stand-out examples in this article, but there are many
others. One of the Web's super powers is its linkability, which is hard to beat
on platforms other than the Web. There seems to be a certain tendency for
cross-platform app frameworks to become less attractive to developers, with the
notable exception of Flutter, which allows for Web as one of its target
platforms. Reasons for not building for the Web are easy to find, but it is
also not hard to find counter-arguments to take these reasons apart. Some of
them rely on outdated or weak assumptions, for example, PWAs not being welcome
on app stores, or platform-specific apps being more secure than PWAs. Others are
things that are in process, like closing the app gap by adding missing Web
platform APIs. Some reasons apply equally to both worlds, for example, for
hiring to be a challenge. I could go on, but in the end it all boils down to the
concrete circumstances your use case needs to be built for. In this article, I
have given a number of really strong arguments for building for the Web, while
also not hiding the fact that the Web is a platform that is still not perfect,
and pointing out that other alternatives exist. And as the three stand-out
examples have shown, the decision is also not mutually exclusive. You can build
a powerful Web app, and have a great, platform-specific application at the same
time. It is up to you to decide if you want to. And as I said in the title:
"Not everyone's currently building for the Web, but probably more people
should". In my humble opinion.
I let the community speak on this event. I have collected all the blog posts
about
Modern Frontends Live
that I could find. If you wrote another, please send a
pull request
or let me know directly, and I will happily link to it.
I had the honor of being asked to contribute some lines to
Jorge del Casar's newsletter called
Estandarte. As you may guess from the name,
the newsletter is written in Spanish, so I wrote
my contribution
in said language (which Jorge thankfully brushed up a little). Find the English
translation below.
In the early days of Project Fugu,
we talked a lot about "closing the app gap". We wanted to put Web developers in
a position where they could implement anything on the Web that they could
implement for platforms like Windows, macOS, Android, iOS, etc. We still want
that, but we have changed our thinking a bit: instead of working down a list of
APIs, we're now looking at what use cases this has enabled. Don't get me wrong,
working down this list was essential, but it left developers a bit in the dark
as to our actual motivation and priorities. To the external observer, some of
what we released may have seemed a bit random. The opposite is the case: from
the start we were partner-driven. Where things fell a bit short was that we
failed to fully convey our vision to developers what this was all about:
enabling Microsoft to release Visual Studio Code, Adobe
to launch Photoshop, BandLab Technologies to
create BandLab, and many projects big and small
more.
Now with the initial batch of APIs done, our focus has shifted on refining and
improving these APIs. Make them more ergonomic to use, be more
privacy-preserving, and more complete in addressing the needs of developers. Be
sure to read my recent article
Is Project Fugu done?,
where I go in more detail regarding our thinking there. My
Twitter DMs and email
are always open and I love hearing developer stories and feature your apps on
the
🐡 Project Fugu API Showcase.
Hey I block cookies by default. Unfortunately your website doesn’t handle that
nicely despite it not needing (IMO) cookies to operate. I'm getting this
error, because blocking cookies also blocks localStorage.
Uncaught DOMException: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.
Please add fallback to js provided localStorage, because it makes the app
unusable.
I don't use cookies in the app at all, but for sure, when I disabled cookies in
Chrome, the app wasn't usable.
All I am using is some innocent localStorage and IndexedDB to persist user
settings like the values of the sliders or the chosen color scheme.
Turns out, with all cookies blocked, Chrome disables a lot of (all?) APIs that
can be used to persist data and thus potentially profile users. Here are the
ones that I found:
The code sample below shows all these APIs and the error messages they throw
when you try to use them with cookies blocked.
localStorage; // Uncaught DOMException: Failed to read the 'localStorage' property from Window: Access is denied for this document.
sessionStorage; // Uncaught DOMException: Failed to read the 'sessionStorage' property from 'Window: Access is denied for this document.
await caches.open('test'); // Uncaught DOMException: An attempt was made to break through the security policy of the user agent.
const openRequest = indexedDB.open('test',1); openRequest.onerror=function(){ console.error(openRequest.error); }; // DOMException: The user denied permission to access the database.
openDatabase('test','1','test',1); // Uncaught DOMException: An attempt was made to break through the security policy of the user agent.
await navigator.serviceWorker.register('.'); // Uncaught DOMException: Failed to register a ServiceWorker for scope ('https://example.com/') with script ('https://example.com/'): The user denied permission to use Service Worker.
await navigator.storage.getDirectory(); // Uncaught DOMException: Storage directory access is denied.
webkitRequestFileSystem( window.PERSISTENT, 1, ()=>{}, (err)=> console.error(err) ); // DOMException: An ongoing operation was aborted, typically with a call to abort().
webkitRequestFileSystem( window.TEMPORARY, 1, ()=>{}, (err)=> console.error(err) ); // DOMException: An ongoing operation was aborted, typically with a call to abort().
Did I miss anything? If so, please let me know!
The fix for the Issue was annoying, but simple. Always
try...catch
any potentially blocked calls:
Please report any other errors you
encounter (I don't care for the analytics script failing). And thanks,
@JakubekWeg for caring enough to having opened
this Issue! Jakub is the proof that users exist who block any and all cookies.
Check your error logs, you might be losing users, too!
(On a tangent, MDN is completely broken
with cookies blocked, too. I was about to report this problem (because I care
and love MDN 😍), when I discovered a
PR is already under way that fixes the
Issue. Thanks,
@bershanskiy!)
It allows interested parties to get a filterable list of all the apps, big and small, that use a given API.
Need to prove that we're building obscure-sounding APIs like the Web Serial API for a reason? Select the API's chip and there goes a list of all the apps that use it:
Of course the Project Fugu API Showcase is contained in itself (yay, recursion 🎉), which means on supporting browsers you can use it to share it (or any other of the contained apps) with your followers:
Please help spread the word and use this in discussions with the people you work with (whose apps you—or they—are obviously most welcome to add to the showcase):