Frontend
Shipping a small offline-first React Native app in a weekend
A simple notes app is a good stress test for whether you actually understand React Native's storage and navigation story, not just its components.
Last updated September 17, 2026
A notes app sounds like a toy project, which is exactly why it's a good one. It's small enough to finish in a weekend but touches every part of the stack that actually matters in a mobile app: local persistence, navigation, and behavior under bad network conditions — none of which show up if you only ever build against a live API on a good wifi connection.
Storage first, UI second
The instinct is to start with screens and components. The better order is to decide how data survives an app restart before writing a single screen, because that decision shapes everything downstream. For a notes app, a simple key-value or small embedded database (something like MMKV or a lightweight SQLite wrapper) is enough — you don't need a sync engine to start, you need writes to not disappear when the OS kills your app in the background, which it will, aggressively, on both platforms.
The mistake I made the first time was reaching for React state as if it were storage. State disappears on remount; a background app suspension is not guaranteed to preserve it. Every note edit has to hit disk on its own, not just live in a useState until some later "save" action fires.
Navigation state isn't app state
React Navigation makes it easy to blur the line between "what screen am I on" and "what data is the app tracking," because both live in similar-looking objects. Keep them separate. The current note being edited is app state that belongs in your storage layer or a store; which screen is currently mounted is navigation's problem and shouldn't leak into your data model. Where this bites people: passing a full note object as a navigation param instead of just its ID, then editing a stale copy that never gets written back because the source of truth was the param, not storage.
Going offline is where the real bugs show up
Everything works when the phone has a connection. Turn on airplane mode and the actual gaps appear: a save button that silently fails because it assumed a network call would succeed, a list screen that shows a blank state because the fetch it depended on threw, a sync indicator that spins forever instead of failing visibly. For a genuinely offline-first app, every write path needs a local-first success path that doesn't depend on the network at all, with sync as a separate, retryable concern layered on top — not a prerequisite for the write to "count."
The payoff of building something this small end to end is that you hit these failure modes in an afternoon instead of discovering them in production three months into a bigger app, once they're expensive to fix because half the codebase already assumes the network is there.
Tags
Related posts