Deep dive2026
Roamkit logo

Roamkit

A travel toolkit that keeps working when your signal does not.

Role
Solo: product, design and mobile

Roamkit is an offline-first travel app: one Expo codebase shipping to iOS, Android, and the web, packed with the tools you actually reach for abroad. Currency and unit converters, tip and split, a world clock, a phrasebook that speaks, a real LED flashlight with SOS, sun times, a compass, a trip budget, and a 57-article survival guide. Every single one works in airplane mode, which is the entire point.

Overview

Roamkit is built with Expo and Expo Router, React Native 0.85, and React 19. The home screen is a grid of tools driven by a single catalog file, so adding a tool is a data entry plus a route. A dark navy design system with per-tool identity colors keeps it feeling like one product instead of eleven small ones.

Monetization is a one-time 4.99 Pro unlock through RevenueCat: no subscription, no ads, no tracking. The production build is through Google Play review with real billing enabled.

The problem

Travel utilities fail exactly when you need them: at customs with no SIM, in a mountain town with one bar, on a plane. Most currency apps are a thin skin over an API call, so offline they show you a spinner and an apology.

The requirement was strict: every tool must produce a correct, honest answer with zero connectivity, and clearly label how fresh its data is.

Three tiers of truth

The heart of the app is the rate store, a three-tier fallback for exchange rates. Tier one is a bundled snapshot that ships inside the JS bundle itself, so conversion works on the very first launch with the network off. Tier two is the last successful fetch, cached on-device. Tier three is a live refresh from a keyless public rate API when the app is online and the data is stale.

Reads never touch the network: the store returns the best available table instantly (memory, then cache, then bundled), and refreshes happen silently in the background. Concurrent screens share one in-flight request, and staleness is defined as older than 12 hours or past the feed's own advertised next-update time. The footer always tells the truth: live rates, saved rates, or built-in rates as of a date.

System map
Expo appiOS + Android + webTool grid10 tools + survival guideDevice APIstorch, GPS, TTS, sensorsRevenueCat$4.99 one-timeRate storethree-tier fallbackBundled snapshotships in the appAsyncStorage cachelast known ratesRate feedopen.er-api.com
drag to exploreReads never wait on the network; refresh happens quietly in the background.

Why this stack

Expo earns its keep here because the tools lean hard on device hardware through one API surface: the flashlight drives the actual LED torch through the camera module, the compass reads the OS fused heading with a raw magnetometer fallback, sun times come from GPS plus pure astronomy math, and the phrasebook speaks through on-device text-to-speech. No servers, no accounts, no backend at all.

Offline needs no cleverness for most tools: unit conversion is ratio math, the world clock uses the IANA timezone database already baked into the JavaScript engine, phrases are a static array, and sunrise math is an almanac formula. The only tool that genuinely needs the internet sometimes is currency, which is why it got the three-tier treatment.

The tools, briefly

Currency converts and compares 30 curated currencies, expandable to 162 with Pro. Tip and split has a round-up-per-person mode that folds the rounding back into the tip so the rows still sum, because a split that does not add up is a bar argument waiting to happen. The flashlight has light, strobe, and SOS modes, and the SOS is real ITU Morse timing: 220 millisecond units, three-unit dashes, hand-sequenced dots and dashes.

The phrasebook covers 20 essential phrases in 9 languages with tap-to-copy and tap-to-hear. The survival guide is 57 plainly written offline articles with a stop-word-stripping search, including such timeless advice as not chasing the snake that just bit you for a photo.

One conversion, offline and online

Offline first launch: the currency screen mounts, the rate store finds no memory or cache, normalizes the bundled snapshot, and converts through a USD pivot: amount divided by the source rate, times the target rate. A locale-tolerant parser handles both comma and dot decimals, because Android keyboards enjoy chaos, and an earlier naive parse could be off by a factor of a thousand on money. That one got fixed with prejudice.

Online, the same mount triggers a silent refresh: if the table is stale, one 8-second-capped fetch updates memory and cache, results recompute live, and the footer flips to live rates. The trip budget tool reuses the exact same store and conversion path, so an expense logged in yen converts with the same honesty rules as the converter.

Privacy and the Pro gate

There is no account and no analytics, and the camera permission exists solely to switch on the torch: the store listing and permission copy both promise no photos, ever, and the code never opens a preview. Android permissions that Play flags as risky are explicitly blocked in the app config.

The Pro unlock is guarded by a three-way gate: billing must be enabled, a platform RevenueCat key must exist, and only then can a purchase grant the entitlement. On the static web build neither condition holds, so Pro simply cannot be granted there, even by hand-editing local storage. RevenueCat itself is lazy-loaded so development builds without native billing modules run untouched.

Challenges and honest tradeoffs

Cross-platform hardware is where the fun lives. The web has no LED, so the flashlight falls back to a max-brightness white screen. The compass on some devices throws on the fused heading API, so a raw magnetometer path smooths the vector, not the angle, because averaging angles across the 359-to-0 wrap does exciting things to a compass needle.

The bundled data is kept deliberately small: 30 rates in the bundle rather than all 162, with the full catalog resolved through a few kilobytes of name-and-flag metadata. And the SOS screen refuses to let the phone sleep, because a sleep timer killing your distress signal is the kind of bug you only get to ship once.

Outcomes

Roamkit is feature-complete for v1: ten live tools plus the survival guide, a coherent design system, and a web build on Vercel from the same codebase. The production Android build is in Google Play review with real billing enabled and testers onboard.

The offline-first architecture proved itself in the details: one shared rate store powers two tools, network usage dropped to roughly one call per day, and every screen can tell you exactly how much to trust the number it just showed you.

Built with
React NativeExpoExpo RouterAsyncStorageRevenueCatEASreact-native-webVercel
At a glance
10
Tools, all working offline
57
Offline survival guide articles
~1/day
Network calls after the rate store refactor
$4.99
One-time Pro. No subscription, no ads

Want to see more?

Explore the rest of my work, or get in touch about a project.