All projects
In Progress · since 2026 ·
react nativeexposqlite

coinwise

A minimalist, local-first expense tracker.


coinwise

coinwise

A minimalist, local-first expense tracker for Android.

coinwise is a calm money app that does one thing well: it tells you where your month is going. No budgets to babysit, no ads, no account, no cloud. Your data lives on your device and nowhere else. Built with Expo and React Native, it pairs a deliberately quiet interface with a surprisingly capable engine underneath - recurring bills, multi-currency travel spend, buckets, and multiple languages, all offline-first.


What it is

coinwise tracks your monthly spending without trying to turn you into a budgeting spreadsheet. It’s built around how money actually moves:

  • Everyday transactions - log an expense or income in a couple of taps.
  • Recurring transactions - rent, subscriptions, salary. Set the cadence once; coinwise projects them forward so your month is always complete.
  • Buckets - group one-off spend for a trip or a project, and optionally fold it into (or keep it out of) your monthly total.

It’s local-first and single-device by design: there’s no sign-up, no server, and nothing leaves the phone unless you explicitly export it.


Why it exists

Most expense trackers fail in the same ways: they’re bloated, plastered with ads, gated behind a subscription, or they assume you want to build a strict budget and feel bad when you miss it. They also tend to hold your financial data hostage in someone else’s cloud.

coinwise is a reaction to all of that:

  • Calm over busy. A big, honest monthly number and a clean list - not twelve dashboards.
  • Private by default. Everything is stored locally in SQLite on the device. No account, no analytics-on-your-spending, no sync server to trust.
  • Built for real spending shapes. Recurring bills and bounded events (a holiday, a house move) are first-class, not afterthoughts.

It’s also a personal craft project - a chance to build a genuinely polished, production-shaped mobile app end to end, from data model to design system.


Core features

FeatureWhat it does
Fast captureAdd income or expense through a modal flow with category, note, and date - minimal friction.
🔁 Recurring transactionsDaily / weekly / monthly / yearly cadences with a real occurrence engine. coinwise materializes concrete entries over a rolling 12-month horizon, supports pausing, and normalizes everything to a monthly-equivalent view.
🧺 BucketsGoal/event buckets with start and end dates and an include-in-month toggle, so a trip’s spend can sit inside or outside your monthly total.
💱 Multi-currency30 currencies with live ECB rates (via the free Frankfurter API), cached locally with a 24h TTL so it works offline. The exchange rate is frozen onto each transaction at entry time, keeping historical totals accurate forever.
🌍 4 languagesEnglish, German, French, and Spanish - fully translated across the app, following your device locale with live in-app switching.
🔔 Smart remindersLocal notifications only: gentle rotating spending nudges plus per-recurring due-date heads-ups with a configurable lead time.
🏷️ Custom categoriesBuild your own categories alongside the sensible defaults.
📤 CSV exportOne tap to export your data as CSV and share it out - your data is yours to take.
🌗 Dark modeSystem / light / dark with a manual override, applied consistently across navigation, status bar, and the Android navigation bar.
📈 Monthly overviewA hero balance, a period picker, and a spending chart.

Vision

coinwise stays intentionally small, but there’s room to grow without betraying the “calm and private” core. Directions being explored:

  • Optional end-to-end encrypted sync for people with more than one device - opt-in, never required.
  • Smarter insights - lightweight trends and category breakdowns that inform without nagging.
  • Home-screen widgets for at-a-glance monthly spend.
  • iOS support to bring the same experience to more devices.

The guardrail for every future feature: it must keep the app quiet, and it must keep your data yours.


Technical details

Stack

LayerChoice
RuntimeExpo SDK 56 (managed), React Native 0.85, React 19
LanguageTypeScript (strict)
NavigationExpo Router - file-based routes, typed routes, Stack.Protected route guards
StylingNativeWind 5 + Tailwind v4 (token-driven, no inline colors)
Databaseexpo-sqlite (on-device only)
ORMDrizzle ORM - schema-first, typed queries, committed migrations, live queries
Formsreact-hook-form + Zod (validation shared by forms and the FX API boundary)
Datesdate-fns
i18ni18next + react-i18next + expo-localization
Notificationsexpo-notifications (local only)
Animationreact-native-reanimated 4 + worklets
ChartsSkia + wagmi-charts
Iconslucide-react-native
Local KVreact-native-mmkv
UI bits@gorhom/bottom-sheet, FlashList

Engineering decisions

  • Local-first, reactive state. State lives close to the data: the UI reacts to Drizzle live queries over SQLite and to MMKV reactive hooks for preferences. No global state library is needed - the database is the source of truth, and the screens simply subscribe to it.
  • Money is never a float. All amounts are stored as integer minor units with hand-rolled formatting (locale-correct symbol placement). This sidesteps an entire class of rounding bugs.
  • FX snapshotting. When you log a foreign-currency expense, the exchange rate is captured and stored on that transaction. Past months never silently shift when rates change - your history stays truthful.
  • Offline-resilient currency. ECB rates are fetched from a free, key-less API, validated with Zod, and cached in MMKV with a TTL, so the app degrades gracefully without a connection.
  • Recurring as a reconciler. Rather than computing recurrences on the fly, an engine materializes concrete transaction rows forward and reconciles them on each app open - pruning the future when you edit, respecting pauses, and keeping projections consistent.
  • Clean routing/UI split. app/ routes are thin re-exports; all real UI lives under features/<name>/, keeping navigation and screens decoupled.
  • Design-system driven. Layout and tokens come from companion wireframe and design-system files — colors, radii, and type are tokens, never one-offs.

Get & use coinwise

Install (Android APK)

  1. Download the latest release: Coinwise APK.
  2. On your phone, allow installs from your browser/file manager (Settings → Apps → Special access → Install unknown apps).
  3. Open the APK to install, then launch coinwise.

First run

  1. Walk through the short onboarding - enter your name, pick a default currency and period-start day, and set your preferences.
  2. Tap the add button to log your first transaction.
  3. Add your fixed costs under Recurring, and create a Bucket the next time you take a trip.

Build from source

coinwise is a managed Expo app targeting Android. Because it relies on native modules (MMKV, Skia, Reanimated), run it via a development build, not Expo Go.

git clone https://github.com/elratto21/coinwise
cd coinwise
pnpm install

# Create/run an Android development build
pnpm expo run:android

Uses pnpm for all package management.


coinwise - track your month, keep your data.