Building an offline-first travel app in .NET MAUI (on-device OCR, currency & maps, no backend)
A build note from Horizon Software , a one-person Android studio. WanderWallet is a travel budget app, and the whole thing runs on the phone: no account, no backend, no cloud. Here's how the parts that look like they need a server actually work without one. The one constraint that shaped everything WanderWallet has a single non-negotiable rule: it has to work with no signal. You're three…
WanderWallet is a travel budget app developed by Horizon Software, which runs entirely on the user's phone without relying on a server or cloud. The app's design is guided by the rule of working seamlessly without any signal. This constraint drives several critical architectural decisions, preventing the need for user login, server communication, and the usage of cloud APIs for any feature. The stack used for the app includes .NET MAUI, CommunityToolkit.Mvvm, sqlite-net-pcl for storage, and SkiaSharp for drawing.
The app's features that initially seemed to require a backend are, in fact, the most challenging to implement without one. These include currency conversion, on-device receipt OCR, and an offline map without any map SDK.
To ensure the app remains functional in airplane mode, exchange rates are fetched offline during the initial connection and then cached locally. Whenever a currency conversion is needed, the app performs local arithmetic using the cached exchange rates. The conversion rate is frozen at the time of expense entry, preventing the historical prices of past expenses from being affected by rate fluctuations.
For receipt OCR, the app utilizes the Plugin.Maui.OCR, which runs text recognition directly on the device using the platform's built-in recognizer, ML Kit on Android. This approach avoids sending photos of receipts to external servers and ensures that the app can extract essential details like amount, date, and merchant without any network dependency.
The app also features an offline map rendered using SkiaSharp, a simple yet effective method. The map is based on a bundled equirectangular world image, and the conversion of latitude/longitude to canvas coordinates is handled through a straightforward mathematical projection. This approach eliminates the need for a mapping SDK, tiles, API keys, or network connections, and the map is rendered directly onto a PNG for sharing.
Additionally, the app includes a small bundle of country centroids for identifying places even when offline.
While the app runs entirely offline, it does have two network connections: one for optional exchange-rate refreshes and another for displaying ads (using AdMob via Plugin.MauiMtAdmob, with Google's UMP for consent). All other aspects, including trips, expenses, receipts, the map, and backups, are handled entirely locally. Despite these network connections, the app remains entirely usable without internet connectivity, with its only limitation being slightly outdated exchange rates.
Overall, WanderWallet demonstrates the effectiveness of an offline-first approach in creating a travel app that is entirely usable without a signal. This approach ensures users can manage their budgets, capture receipts, and navigate their travels without the need for an account or any uploaded data. WanderWallet is free on Google Play, and there's a feature rundown available for more detailed insights into its implementation.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written; read the original for the full account.


