Tags: app

1792

sparkline

Friday, May 15th, 2026

Native Apps Should Be Avoided Whenever Possible — No One’s Happy

The browser is the security boundary. Websites operate within it. Native apps bypass it.

Like I said last year:

But there’s still one thing that native apps do better than the web. If you want to be able to monitor and track users to an invasive degree, the web can’t compete with the capabilities of native apps. That’s why you’ll see so many websites on your mobile device that implore to install their app from the app store.

This piece goes into the details:

Most native apps collect far more data than their website equivalents ever could. They request permissions to hardware, sensors, and background processes that browsers deliberately restrict. The third-party software embedded in these apps frequently transmits your location, device identifiers, and behavioral data to third parties before you even see a consent prompt.

Tuesday, April 7th, 2026

TinyStart

Sometimes I look back through my blogging archives and notice what’s changed over time.

For example, I used to write quite enthusiastically about the arrival of a new operating system from Apple. That is no longer the case, to put it mildly. I’m currently holed up on Sequioa, trying to resist all the nudgings to “upgrade” to the tacky design nightmare that is Tahoe. I feel like the protagonist of Pluribus.

I used to write about software I really liked. Sometimes it was software made by Apple. More often it was from some independent developer.

Like, I remember how much I loved a little application called Quicksilver. It just did one thing. You pressed control and space and then started typing the name of any programme installed on your computer. After a few characters Quicksilver would show you the match, you hit enter and the programme launched.

If that process sounds familiar, it’s because Apple ended up incorporating it into their own Spotlight feature. Quicksilver got sherlocked (ask your parents).

Recently though, Spotlight got worse and worse at doing its one job. It’s been laggy and inaccurate, even though I set my Spotlight indexing options to only index the Applications folder.

Then I found TinyStart. It’s like Quicksilver reborn!

A tiny launcher for macOS, fast and focused on the essentials.

Actually, it does double duty. As well as being an application launcher, it’s also an emoji picker. 👍

Best of all, not only is TinyStart a return to the focus and quality of software of yore, it’s also a return to the pricing model. You buy the software—for a measly €5—and that’s it. You own it now. There’s no subscription you have to pay every month.

I love everything about this.

Thursday, April 2nd, 2026

Mistrust

Four years ago I wrote about something that has long puzzled me in the world of front-end development. Trust:

The mindset I’ve noticed is that many developers are suspicious of browser features but trusting of third-party libraries.

Developers are more likely to trust, say, Bootstrap than they are to trust CSS grid or custom properties. Developers are more likely to trust React than they are to trust web components.

That post got some thoughtful responses but I never really understood the imbalance of trust and suspicion:

I’m kind of confused by this prevalent mindset of trusting third-party code more than built-in browser features.

But something happened recently that helped me understand that mindset better.

I wrote a while back about how the datalist element on iOS has been completely fucked up. It’s worse than if Safari simply didn’t support it.

Breaking the web like that should be a five-alarm fire, but nobody is in any rush to fix it. I recall a similar lackadaisical attitude when Safari completely broke their implentation of IndexedDB.

I had it in my head that browser features followed a forward path generally. They’d be iterated on and improved on to iron out any glitches, but it was reasonable to expect things to get better with each new version of a browser.

Now I see that’s not necessarily the case.

Had I used an over-engineered JavaScript library instead of the datalist element, I wouldn’t be facing the current situation of having to use browser-sniffing to avoid sending a standard HTML element to any browser on iOS.

Sure, that third-party JavaScript would mean that users are downloading more code, and it probably wouldn’t work well with assistive technology, but as long as I didn’t touch it, it would continue to work. That should be true of web standards—I should be able to use them secure in the knowledge that they won’t suddenly shit the bed.

Perhaps I should be grateful to Apple for dispelling my naïveté. I now have much more empathy and understanding for web developers who are suspicious of web standards and prefer to use third-party libraries instead.

Good job, Apple. Happy anniversary.

Bruce Lawson’s personal site  : Apple at 50: my top five Apple moments

Never forget:

  • The time Apple lied to the UK regulator
  • The time when Apple told the EU that Safari is 3 different browsers
  • When Apple tried to shut the UK investigation down
  • When Apple’s VP of Finance got caught lying under oath
  • When Apple tried to wreck all EU Web Apps

Monday, March 9th, 2026

Installing web apps

I have websites in my dock on my computer. I have websites on the home screen of my phone. When I open these websites from the dock or from the home screen, they behave just like native apps. It’s brilliant!

But knowing that you can add a website to the dock or to the home screen remains arcane knowledge. If you don’t know it’s possible, most web browsers aren’t going to tell you it’s an option. As a site owner, you pretty much have to explain to your users what they can do.

Lately it feels like there’s been some movement to change this situation. Or, at the very least, there’s been some discussion.

As a site owner, what you want is a way for someone visiting your site to press a button to initiate the process of adding the site to the dock or the home screen.

From what I can see from the discussion, there are two contenders for how to do this: BeforeInstallPromptEvent versus navigator.install.

I’ve used both APIs in production, so I’d like to offer my balanced feedback on both:

  • BeforeInstallPromptEvent sucks.
  • navigator.install rocks.

To add more detail…

The BeforeInstallPromptEvent API relies on you capturing and delaying an event that may or not fire at all.

Based on some arbitrary heuristics, Chrome—for example—will prompt the user to install the current website. This easily-dismissable prompt looks indistinguishable from a prompt to sign up to a newsletter or grant permission for cookies, so most people dismiss it. The idea with BeforeInstallPromptEvent is that you capture that prompt, prevent it from prompting, and then release it when you think it’s an appropriate time.

If you think it takes mental gymnastics to understand that, just imagine what it’s like trying to implement it!

The whole thing rests on this flawed idea of an install prompt being shown when certain conditions are met. Other browser vendors rightly point out that users should be able to install any website they want. Ideally it should have a manifest file. But making a service worker a requirement is a step too far (and I say that as someone who literally wrote a book about service workers).

Contrast that with the Web Install API, AKA navigator.install.

Based on a user interaction—like a click on a button—the browser initiates the installation process. The user still has to confirm they want to do this, of course. You know how geolocation or web notifactions work? It’s like that. You can’t trigger any of those APIs without the user’s permission.

That’s it. No contest.

It would be absolutely wonderful if more browsers supported navigator.install. It would be a pain in the ass if they decided to support BeforeInstallPromptEvent instead.

Wednesday, March 4th, 2026

Madra Teanga - Open Source Irish Language Programming

An open source project that has already produced a great app for learning Irish—programmed in a language called Draíocht (sin “magic” as Béarla)!

I’m supporting this on Open Collective.

Saturday, November 29th, 2025

Installing web apps

Safari, Chrome, and Edge all allow you to install websites as though they’re apps.

On mobile Safari, this is done with the “Add to home screen” option that’s buried deep in the “share” menu, making it all but useless.

On the desktop, this is “Add to dock” in Safari, or “Install” in Chrome or Edge.

Firefox doesn’t offer this functionality, which as a shame. Firefox is my browser of choice but they decided a while back to completely abandon progressive web apps (though they might reverse that decision soon).

Anyway, being able to install websites as apps is fantastic! I’ve got a number of these “apps” in my dock: Mastodon, Bluesky, Instagram, The Session, Google Calendar, Google Meet. They all behave just like native apps. I can’t even tell which browser I used to initially install them.

If you’d like to prompt users to install your website as an app, there’s not much you can do other than show them how to do it. But that might be about to change…

I’ve been eagerly watching the proposal for a Web Install API. This would allow authors to put a button on a page that, when clicked, would trigger the installation process (the user would still need to confirm this, of course).

Right now it’s a JavaScript API called navigator.install, but there’s talk of having a declarative version too. Personally, I think this would be an ideal job for an invoker command. Making a whole new install element seems ludicrously over-engineered to me when button invoketarget="share" is right there.

Microsoft recently announced that they’d be testing the JavaScript API in an origin trial. I immediately signed up The Session for the trial. Then I updated the site to output the appropriate HTTP header.

You still need to mess around in the browser configs to test this locally. Go to edge://flags or chrome://flags/ and search for ‘Web App Installation API’, enable it and restart.

I’m now using this API on the homepage of The Session. Unsurprisingly, I’ve wrapped up the functionality into an HTML web component that I call button-install.

Here’s the code. You use it like this:

<button-install>
  <button>Install the app</button>
</button-install>

Use whatever text you like inside the button.

I wasn’t sure whether to keep the button element in the regular DOM or generate it in the Shadow DOM of the custom element. Seeing as the button requires JavaScript to do anything, the Shadow DOM option would make sense. As Tess put it, Shadow DOM is for hiding your shame—the bits of your interface that depend on JavaScript.

In the end I decided to stick with a regular button element within the custom element, but I take steps to remove it when it’s not necessary.

There’s a potential issue in having an element that could self-destruct if the browser doesn’t cut the mustard. There might be a flash of seeing the button before it gets removed. That could even cause a nasty layout shift.

So far I haven’t seen this problem myself but I should probably use something like Scott’s CSS in reverse: fade in the button with a little delay (during which time the button might end up getting removed anyway).

My connectedCallback method starts by finding the button nested in the custom element:

class ButtonInstall extends HTMLElement {
  connectedCallback () {
    this.button = this.querySelector('button');
    …
  }
customElements.define('button-install', ButtonInstall);

If the navigator.install method doesn’t exist, remove the button.

if (!navigator.install) {
  this.button.remove();
  return;
}

If the current display-mode is standalone, then the site has already been installed, so remove the button.

if (window.matchMedia('(display-mode: standalone)').matches) {
  this.button.remove();
  return;
}

As an extra measure, I could also use the display-mode media query in CSS to hide the button:

@media (display-mode: standalone) {
  button-install button {
    display: none;
  }
}

If the button has survived these tests, I can wire it up to the navigator.install method:

this.button.addEventListener('click', async (ev) => {
  await navigator.install();
});

That’s all I’m doing for now. I’m not doing any try/catch stuff to handle all the permutations of what might happen next. I just hand it over to the browser from there.

Feel free to use this code if you want. Adjust the code as needed. If your manifest file says display: fullscreen you’ll need to change the test in the JavaScript accordingly.

Oh, and make sure your site already has a manifest file that has an id field in it. That’s required for navigator.install to work.

Thursday, October 30th, 2025

Aleth Gueguen is speaking at Web Day Out

Almost two months ago, I put out the call for speaker suggestions for Web Day Out. I got some good responses—thank you to everyone who took the time to get in touch.

The response that really piqued my interest was from Aleth Gueguen. She proposed a talk on progressive web apps, backed up with plenty of experience. The more I thought about it, the more I realised how perfect it would be for Web Day Out.

So I’m very pleased to announce that Aleth will be speaking at Web Day Out about progressive web apps from the trenches:

Find out about the most important capabilities in progressive web apps and how to put them to work.

I’m really excited about this line-up! This is going to be a day out that you won’t want to miss. Get your ticket for a mere £225+VAT if you haven’t already!

See you in Brighton on 12 March, 2026!

Sunday, October 26th, 2025

Layoutit Terra - CSS Terrain Generator

It’s wild what you can do with CSS these days!

Monday, September 1st, 2025

Atlas of Space

A nifty interactive 3D map of our solar system

Thursday, August 28th, 2025

Optimizing PWAs For Different Display Modes — Smashing Magazine

There’s really good browser support for display-mode media queries and this article does a really good job of running through some of the use cases for your progressive web app.

Thursday, August 7th, 2025

Progressive web apps

There was a time when you needed to make a native app in order to take advantage of specific technologies. That time has passed.

Now you can do all of these things on the web:

  • push notifications,
  • offline storage,
  • camera access,
  • and more.

Take a look at the home screen on your phone. Looking at the apps you’ve downloaded from an app store, ask yourself how many of them could’ve been web apps.

Social media apps, airline apps, shopping apps …none of them are using technologies that aren’t widely available on the web.

“But”, you might be thinking, “it feels different having a nice icon on my homescreen that launches a standalone app compared to navigating to a bookmark in my web browser.”

I agree! And you can do that with a web app. All it takes the addition of one manifest file that lists which icons and colours to use.

If that file exists for a website, then once the user adds the website to their homescreen it will behave just like native app.

Try it for yourself. Go to instagram.com in your mobile browser and it to your homescreen (on the iPhone, you get to the “add to home screen” option from the sharing icon—scroll down the list of options to find it).

See how it’s now an icon on your home screen just like all your other apps? Tap that icon to see how it launches just like a native app with no browser chrome around it.

This doesn’t just work on mobile. Desktop browsers like Chrome, Edge, and Safari also allow you to install web apps straight from the browser and into your dock.

About half of the icons in my dock are actually web apps and I honestly can’t tell which is which. Mastodon, Instagram, Google Calendar, Google Docs …I’m sure most of those services are available as downloadable desktop apps, but why would I bother doing that when I get exactly the same experience by adding the sites to my dock?

From a business perspective, it makes so much sense to build a web app (or simply turn your existing website into a web app with the addition of a manifest file). No need for separate iOS or Android developer teams. No need to play the waiting game with updates to your app in the app store—on the web, updates are instant.

You can even use an impressive-sounding marketing term for this approach: progressive web apps:

A Progressive Web App (PWA) is a web app that uses progressive enhancement to provide users with a more reliable experience, uses new capabilities to provide a more integrated experience, and can be installed. And, because it’s a web app, it can reach anyone, anywhere, on any device, all with a single codebase. Once installed, a PWA looks like any other app, specifically:

  • It has an icon on the home screen, app launcher, launchpad, or start menu.
  • It appears when you search for apps on the device.
  • It opens in a standalone window, wholly separated from a browser’s user interface.
  • It has access to higher levels of integration with the OS, for example, URL handling or title bar customization.
  • It works offline.

But there’s still one thing that native apps do better than the web. If you want to be able to monitor and track users to an invasive degree, the web can’t compete with the capabilities of native apps. That’s why you’ll see so many websites on your mobile device that implore to install their app from the app store.

If that’s not a priority for you, then you can differentiate yourself from your competitors by offering your users a progressive web app. Instead of having links to Apple and Google’s app stores, you can link to a page on your own site with installation instructions.

I can guarantee you that users won’t be able to tell the difference between a native app they installed from an app store and a web app they’ve added to their home screen.

Tuesday, August 5th, 2025

Vibe code is legacy code | Val Town Blog

When you vibe code, you are incurring tech debt as fast as the LLM can spit it out. Which is why vibe coding is perfect for prototypes and throwaway projects: It’s only legacy code if you have to maintain it!

The worst possible situation is to have a non-programmer vibe code a large project that they intend to maintain. This would be the equivalent of giving a credit card to a child without first explaining the concept of debt.

If you don’t understand the code, your only recourse is to ask AI to fix it for you, which is like paying off credit card debt with another credit card.

It’s time for modern CSS to kill the SPA - Jono Alderson

SPAs were a clever solution to a temporary limitation. But that limitation no longer exists.

Use modern server rendering. Use actual pages. Animate with CSS. Preload with intent. Ship less JavaScript.

Sunday, July 27th, 2025

map

Checked in at Ulster Hall for NOTIFY, Dervish, Cormac McCarthy, MGCE Concert Orchestra, and 5 more…. Dervish!

Thursday, July 24th, 2025

Welcome to Medieval Murder Maps

CSI London, York, and Oxford:

Discover the murders, sudden deaths, sanctuary churches, and prisons of three thriving medieval cities.

Saturday, July 19th, 2025

Vibe coding and Robocop

The short version of what I want to say is: vibe coding seems to live very squarely in the land of prototypes and toys. Promoting software that’s been built entirely using this method would be akin to sending a hacked weekend prototype to production and expecting it to be stable.

Remy is taking a very sensible approach here:

I’ve used it myself to solve really bespoke problems where the user count is one.

Would I put this out to production: absolutely not.

Friday, July 18th, 2025

Frame of preference – Aresluna

Marcin has outdone himself this time. Not only has he created an exhaustive history of the settings controls in Apple interfaces, he’s gone and made them all interactive!

While it’s easy to be blown away by the detail of the interactive elements here, it’s also worth taking a moment to appreciate just how good the writing is too.

Bravo!

Monday, July 7th, 2025

Checked in at Ard Bia at Nimmos. Breakfast at the Spanish Arch — with Jessica map

Checked in at Ard Bia at Nimmos. Breakfast at the Spanish Arch — with Jessica