Local-First Software: When the Cloud Is the Wrong Default
Hosted infrastructure is the default for a reason, but a tool used by one person on one machine often pays for a scaling problem it will never have.
Every new piece of software seems to start from the same assumption: a hosted database, an API layer, a deploy pipeline, an uptime target. That assumption is correct for most things worth building. It is also applied automatically to a category where it rarely earns its cost: a tool one person runs on one machine, for a process nobody else needs to touch at the same time.
Local-first means keeping the parts of a system that can run on the machine actually running there, and reserving network calls for the things that genuinely have to leave the building.
What actually stays local
Storage is the easiest one. SQLite handles a single-user or single-team dataset without a hosted database, a connection pool, or a monthly bill, and it survives a restart the same way a hosted database would. Compute is the less obvious one: text-to-speech, image processing, and plenty of transformation work that gets defaulted to a cloud API can run locally just as well, often faster, since there is no round trip.
What stays remote is whatever genuinely cannot happen locally: a call to a model that only exists as a hosted API, an upload to a platform that only accepts uploads over the network. The test is not “can this be local” for its own sake. It is “does this specific step have a real reason to leave the machine,” and most steps in most internal tools do not.
What this looked like in practice
We built a video production dashboard that takes a project from title idea through script, voiceover, render, and a scheduled YouTube upload, all from one interface. SQLite holds the project library. Kokoro TTS generates every voiceover locally, with no per-video API cost and no dependency on a provider being up. FFmpeg assembles the final render from local files. The only two network calls in the entire pipeline are a request to Claude for the script and metadata, and the final upload to YouTube, because those are the two steps that actually require leaving the machine.
That leaves the pipeline usable for everything except those two steps even with no connection at all, and it keeps the per-video cost close to zero for the parts that would otherwise be metered by a vendor per call.
What you give up, honestly
Nothing here is free. A local-first tool is genuinely harder to access from a second device, and multi-device access has to be built deliberately rather than inherited from the platform. Backups are the operator’s responsibility, not a managed service’s, so a local database needs its own backup discipline or it is one dead drive away from losing everything. And none of this scales to many concurrent users on the same dataset; the moment two people need to edit the same project at once, the local-first case for that dataset is over.
These are not reasons to avoid the approach. They are the specific costs that get paid instead of a hosting bill, and pretending they do not exist is how a local-first tool becomes a liability nobody accounted for.
When it is the right call
The clearest fit is a tool with exactly one operator and no requirement to be reached from anywhere but the machine it runs on, which describes a lot of internal production tooling more accurately than teams initially assume. It also fits anywhere the per-unit cost of a cloud service would otherwise scale linearly with volume, since running the equivalent step locally turns a metered cost into a fixed one.
It is the wrong call the moment a second regular user shows up, or the moment the tool needs to be checked from a phone on the way somewhere. Neither of those is a reason to add cloud infrastructure preemptively. They are reasons to add it when they actually happen, which is the same discipline covered in build vs buy: commodity infrastructure is worth paying for exactly when the problem it solves is real, not before.
This is also a specific case of a more general bias worth holding for internal tools: use the boring stack, and don’t reach for infrastructure the problem hasn’t asked for yet, a habit covered more broadly in which internal tools are worth building.
We build tools sized to the problem they actually solve, cloud included only where it earns its place. See the video pipeline case study, or read about how we approach applications.