Built to Last

loading views

The gardener robot from Castle in the Sky, covered in moss

Software should be built as if every version could be the last.

Open any app you purchased a few years ago. Chances are it wants an update, a login, or rent before you can access your data. Maybe it won’t open at all.

Let’s face it. Most software you use today is not built to last.

Subscriptions fund fragility

Subscriptions exist for a reason. Recurring revenue pays for maintenance and keeps developers working on the product.

A lot of software needs constant maintenance because of how it was built. User accounts need a server and a database. Billing needs infrastructure. Every third-party API is a feature the developer rents and does not control. All of it can break, change its price, or disappear.

So the subscription often funds the fragility that justifies the subscription in the first place.

There’s a whole category of software where the core functionality doesn't require any of this. The software could survive for years without a developer touching it. It just wasn't built that way.

Saying no

The alternative is simple to decide but hard to actually pull off.

I have built numerous apps with user accounts and sync services that were dependent on third-party services and APIs. Each one needed me around to keep paying for infrastructure and putting out fires. Without me, they would stop working. I use a new set of constraints to build differently now.

Package everything the app needs inside the app and do all work on-device. Use what the platform already offers before building your own solution and make sure the app still works when any of it fails.

The core functionality happens on the user's device, and nothing outside the device can take it away.

Build for the worst case. If you published one version and disappeared tomorrow, the version people already have should keep working. Don’t build on anything that could expire, like a server that can die or disappear.

This removes the need for entire features and decisions that could bother or confuse users. No user account means no login, no passwords and no account settings. A single payment eliminates billing-related features and annoying plan comparisons. Every feature you don’t need is one less thing that can break, one less thing to test, and one less decision your users have to make.

Not every app can be built to last. A social app needs a server, but a notes app, a reader, or a tracking app does not.

Built to last doesn't mean zero dependencies. That's impossible. Your app depends on the operating system, and the operating system breaks random things on every major update.

Avoid outside dependencies. Pick only the ones most likely to outlive you, and make the app survive their failure.

iCloud will probably exist longer than any app I build. So I use it for sync. But if it's down, the app still works, because it's local-first.

Monetization

Some things like servers, storage, inference and bandwidth cost money every month. A sync service is real infrastructure that requires constant cash flow.

If you need to charge rent, charge it only for parts that truly need it.

Take Obsidian. The app is free, works offline, and stores plain text files. They only charge for sync, because that’s the part that costs money every month.

Without a server or paid APIs there is no monthly cost to pass on, so there is no reason to charge rent. That’s what makes a one-time price the honest option.

Labor obviously isn’t free. A one-time purchase pays for the version you bought, not for every version after it. When a major version needs real new work it’s only fair to charge again.

For a user, it’s an easy tell. If an app has no server and no paid API, its subscription is a choice, not a requirement.

Free upgrades

Hardware gets more powerful every year. What requires a beefy server today will run on-device in a couple of years. We have seen this happening with speech-to-text, text-to-speech, photo processing, offline maps and more. Language models will be next.

If your app does its work exclusively on-device, every hardware generation makes it better without increasing costs for the developer, so it shouldn’t increase the costs for users either. People who bought the app years ago can get the improvement in a regular update.

The cloud will always get more expensive as usage grows while user devices get more capable and cheaper as time passes.

Data

Even software built to last eventually dies, which is why file over app matters.

User data must outlive the app.

Store it in an open format the user can access without you. Let them export everything. If the app stops working, the years of notes, articles, photos and other user data should not disappear with it.

Every version could be the last

That’s the one constraint you choose before writing the first line of code. If this version were the last, it should keep working indefinitely.

Everything else will follow. Keep data on-device. Do the work locally. Depend on the platform, not on third parties. Let nothing expire. Store data in files the user can open without you. Charge only for what costs money every month.