Skip to content
Plazoleta
· Raúl López

Offline-first isn't a checkbox: it's the entire data model

At Jornia we cleared the entire offline backlog before touching sync. What made that possible wasn't a feature list — it was a filter we applied to every single one.

At Jornia, before opening F4 — user accounts and cross-device sync — we asked ourselves an uncomfortable question: how much can you build without that? The answer, after clearing an entire backlog, was: almost everything that matters.

That wasn't an accident. It was a filter applied to every feature, one by one, before a single line of code got written.

The filter, not the list

The offline backlog (docs/backlog-offline-preF4.md) isn't a list of "cool things competitors do." It's that list run through a hard filter: feasible without an account or network, or that degrades gracefully with caching. Everything else gets cut or shelved, no matter how good it looks in a demo.

That filter is what separates "offline-first" from "also works without a connection." The difference shows up in the concrete decisions:

  • Currency conversion per trip uses a cached or manually entered rate, never a mandatory call at the moment you view the expense.
  • The trip map can be downloaded by area in advance (Mapbox TileStore + OfflineManager), actually verified in airplane mode — not "should work without network," but tested without network.
  • Boarding pass scanning parses the IATA BCBP standard entirely on-device. Nothing leaves the phone, and the gate code can be shown with zero coverage. That's the kind of decision that shapes an entire mobile app.

None of these three is hard to justify on its own. What's hard is getting all three to pass the same filter, and then applying that same filter to the next one, and the one after that. That's where offline-first stops being a marketing adjective and becomes an architectural constraint that touches every feature.

Why this is about the data model, not the connection

The easy temptation is to treat "offline" as an add-on case: the app works, and there's also a caching layer for when there's no network. That approach works fine until someone asks for something that actually matters — splitting expenses between travelers, full backup, aggregated stats across all trips — and that's when you find out whether the model holds up.

In the closing analysis for this stage (docs/analisis-offline-v0.11.md) the bar for "actually done" isn't "works on wifi." It's stricter: expense splitting with settlement between travelers, stats computed from data that's already local (flight distance included, using the haversine formula on coordinates the map had already geocoded), full JSON backup export/import with attachments. All of that requires the correct data to already be on the device, not something you can fetch on demand.

That's what I mean by "the entire data model": it's not a caching layer bolted onto an app designed to always be connected. It's designing the source of truth to live locally from day one, and treating the network as something optional that enriches, never as something a feature the user already considers basic depends on.

The real test: airplane mode, for real

The market comparison in that same analysis is telling: against Tripsy, TripIt, and Wanderlog, Jornia's offline support isn't "partial" or "paid" — it's the only row in the table marked as full and free. That doesn't come from a promise in the store listing. It comes from every candidate feature going through the same filter before it got in, and from the offline map being verified by downloading a real area and checking the render in airplane mode, not assuming it "should work."

That discipline has a cost: things that seem easy to justify in the abstract — parsing reservations from email, real-time flight alerts, cross-device sync — get left out of the offline backlog on purpose, because they don't pass the filter. It's not that they don't matter: they belong to another phase (F4, F5, F6 on the roadmap), the one that does depend on the network, and pulling them in early would have diluted the very property that makes the others strong.

What we're taking away

Offline-first isn't decided once. It gets decided on every feature, with the same filter, until it becomes the team's default reflex instead of a checkbox you have to remember to tick.

"Works without a network" and "the correct data already lives on the device" are not the same thing. The first is a property of the connection. The second is a property of the data model, and only the second holds up once the feature gets serious (expense splitting, stats, backup).

Verifying in airplane mode isn't optional. It's the only way "offline" stops being a promise and becomes a checked fact, with an actual map area downloaded and rendered with no data, not a reasonable assumption.


If you're designing something that has to work without a connection and want to compare notes on the filter you used, get in touch.

Got a similar problem?

Tell us about it. You'll be talking straight to whoever writes the code.