The craft

One Flutter codebase, two platforms that feel native

A single codebase that ships to both iOS and Android is an efficiency, not a compromise — but only if the result feels native on each, and only if it is built for the states an app actually spends its life in. Flutter lets us do the first; discipline does the second.

One codebase, two platforms, honestly native

Flutter renders its own interface rather than wrapping each platform's controls, which is exactly why a Flutter app can look identical on two phones — and exactly why it can feel foreign on both if you ignore the conventions each platform's users expect. Native feel is not automatic; it is a set of deliberate choices about navigation, gestures, typography, and the small motions that make an app feel like it belongs.

The payoff, done with that care, is real: one team, one language, one set of business logic, shipping to both stores without maintaining two divergent apps that slowly grow apart. The saving is genuine as long as the platform-specific polish is treated as work to do, not a box already ticked by the framework.

The states an app really lives in

A mobile app spends very little of its life on the screen shown in the store listing. It spends it on first run before anything is set up, offline on a train, mid-sync when a change is saved locally but not yet uploaded, in error when a request fails, and empty when a section has nothing in it yet. Each of those is a screen someone has to design and build.

Sync and offline are where the real difficulty lives, because they force a decision about what is true when the device and the server disagree. An app that pretends connectivity is constant is an app that loses a user's edit the first time the signal drops in a lift. Building for the disconnected case from the start is the difference between an app people trust with something and one they do not.

Built this way, for something worth keeping

Memoria is a Flutter app of exactly this kind — an encrypted, family-shared household organiser, multilingual, production-ready and launching on iOS and Android. It is the sort of app where the offline, sync, and empty states are not edge cases but the everyday, because a household opens it in kitchens and cars, not at a desk on a stable connection.

The discipline is the same one we bring to any mobile build: both platforms, every real state, and data that stays the user's. If you have an app that has to hold up in people's hands rather than in a demo, our approach is on mobile app development.

Questions

People also ask

    Does one Flutter codebase really feel native on both platforms?

    It can, but not automatically — Flutter draws its own interface, so native feel comes from deliberate choices about navigation, gestures, and motion per platform. Done with that care, one codebase ships to both stores without maintaining two divergent apps.

    Why so much emphasis on offline and sync?

    Because a mobile app spends most of its life in states the store listing never shows — first run, offline, mid-sync, error, empty. Sync and offline force a decision about what is true when device and server disagree, and getting it wrong loses a user's edit the moment the signal drops.