Nepal's highways are dotted with small roadside workshops, but finding one when you actually need it bike broken down outside a town you don't know, no signal-strength to spare is a different problem entirely. Mechanic Sathi ("mechanic companion") is a React Native app built to solve exactly that: help travelers find verified roadside workshops, call for help, and do it all even when the connection drops out.
The stack is React Native with Expo for the app itself, and SQLite for local, offline-first storage. That last detail shaped almost every decision in the app.
Why offline-first wasn't optional
Most app tutorials treat offline support as a nice-to-have a cache layer added once the "real" online-first version works. For Mechanic Sathi, that ordering had to be reversed. The people who need this app most are often exactly where connectivity is worst: mountain roads, rural stretches between towns, places where a data connection comes and goes with the terrain.
So workshop listings, ratings, and contact details are stored locally with SQLite from the start, synced opportunistically whenever a connection is available. A traveler searching for the nearest workshop isn't waiting on a network request that might time out they're querying data that's already sitting on their phone.
The app has to assume the network is the exception, not the rule. Everything else follows from that one assumption.
The SOS button is the whole point
Search and ratings matter, but the feature that actually justifies the app's existence is the one-tap emergency SOS call. When something goes wrong on an unfamiliar road, nobody wants to navigate three menus to find a phone number. The SOS flow is intentionally minimal one visible action, no confirmation dialogs standing in the way, connecting a traveler to help as fast as the interface can get out of their way.
Designing for a stressful, time-sensitive moment is a different discipline than designing for a browsing session. Every extra tap in a calm-state feature is a minor annoyance; every extra tap in an emergency flow is a real cost. That distinction shaped the whole interaction design the busiest, most detailed part of the app is the search and discovery experience, and the calmest, sparest part is the one you reach for when you're not calm at all.
Verified listings, not crowdsourced guesses
A directory of roadside workshops is only useful if it's trustworthy. Unverified listings wrong locations, workshops that closed years ago, inflated ratings would undermine the app faster than having no listings at all. Workshops in Mechanic Sathi go through a verification step before they're searchable, and ratings are tied to real completed interactions rather than open-ended reviews anyone could post.
What building this taught me about designing for real conditions
It's easy to design for the phone in your hand, on office Wi-Fi, at a comfortable desk. It's harder and more honest to design for a phone at 40% battery, patchy signal, and a rider who's stressed and in a hurry. Mechanic Sathi pushed me to test on exactly those conditions: airplane mode, low storage, a screen viewed at an angle in bright sunlight. Most of the "polish" work on this app wasn't visual it was making sure the core flow held up when everything around it was working against the user.
How I actually tested the offline behavior
I didn't just assume the offline-first design worked I tested it the way a traveler would actually hit it. That meant toggling airplane mode mid-search, force-closing the app while a sync was in progress, and walking between rooms with a phone set to weak-signal simulation to see how gracefully the app recovered once connectivity returned. The local SQLite queries stayed fast and consistent throughout; the harder problem was making sure a sync that got interrupted halfway through didn't leave the local database in a half-updated state. Handling that cleanly rather than assuming syncs always complete took more iteration than the search feature itself.
I also timed the SOS flow specifically, since that's the one interaction where speed genuinely matters more than anything else in the app. From tapping the button to a call being placed, the goal was to minimize every intermediate step no loading spinner standing between a stressed user and a phone call they need to make right now.
Why Expo and SQLite were the right fit, not just the easy fit
Expo's managed workflow meant less time wiring up native build tooling and more time on the actual offline-sync and SOS logic that makes this app different from a generic directory listing. SQLite was the more deliberate choice: it's a real embedded relational database rather than a simple key-value cache, which mattered once workshop search needed filtering by location, rating, and service type the kind of querying that a flat local cache handles poorly but a proper local database handles natively.
Frequently asked questions
Does Mechanic Sathi work with zero signal at all, or just weak signal?
Search, browsing, and viewing already-synced workshop details work with zero connectivity, since that data lives locally in SQLite. Actions that need a live connection like placing the SOS call itself or pulling brand-new listings obviously still need at least a phone signal to complete.
How are workshops verified before they appear in the app?
Listings go through a verification step before becoming searchable, rather than being accepted purely from open submissions, and ratings are tied to completed interactions rather than open-ended, unverified reviews.
Why build this specifically for Nepal instead of a general roadside-assistance app?
Rural and mountain roads in Nepal have connectivity gaps that a lot of assistance apps built for denser, better-connected markets don't design around at all. Solving for that specific condition offline-first, not offline-tolerant was the actual point of the project.
The code is up on GitHub if you want to see how the offline sync and SOS flow are implemented.
Further reading & references: