Spendwise is a personal finance app built with Expo and React Native. The app is local-first: core financial data lives in on-device SQLite and user preferences live in MMKV.
- Onboarding and profile setup (name + avatar)
- Preferences: theme (system/light/dark) and language
- Accounts: create/edit/delete, opening balance, monthly budget, balance overview
- Categories: create/edit/delete, emoji icons, ordering/reorder UI, monthly budgets
- Transactions: income/expense/transfer, search + filters, detail screen, per-account assignment
- Recurring rules (scheduled transactions): create/edit/remove rules, next-due tracking, upcoming bill checks
- Stats: totals, trends (weekly/monthly breakdown), category breakdowns, top income/expenses
- Insights: monthly trend + spending by category analytics
- Import/Export:
- CSV import (column mapping + preview) and CSV export
- Full JSON backup export and restore
- Currencies and formatting:
- Display currency selection with historical rate recalculation
- Number/date/currency format preferences
- Notifications:
- Budget alerts (approaching/exceeded)
- Upcoming bill reminders
- Low balance alerts
- Weekly spending digest
- Security: optional app lock using device authentication (biometrics/PIN)
- Optional:
- AI chat (OpenAI/Anthropic) using user-provided API keys stored on-device
- Receipt scanning (requires AI key)
- Expo SDK 54 with React Native 0.81
- Expo Router 6 for file-based navigation
- SQLite for primary app data
- Zustand + MMKV for persisted preferences and lightweight app state
- React Query for async queries/mutations over local data and network tasks
- TanStack Form + Zod for forms and validation
- Uniwind for styling
- Jest + React Native Testing Library + Maestro
- Node.js 20+
pnpm- Expo / EAS tooling as needed for device builds
pnpm installCopy .env.example to .env and adjust values for your machine.
cp .env.example .envOn Windows PowerShell, use:
Copy-Item .env.example .envAt minimum, the current env schema expects:
EXPO_PUBLIC_APP_ENVEXPO_PUBLIC_API_URLEXPO_PUBLIC_VAR_NUMBEREXPO_PUBLIC_VAR_BOOLAPP_BUILD_ONLY_VAR(optional)
If EXPO_PUBLIC_ASSOCIATED_DOMAIN is not used, omit it entirely instead of leaving it blank.
EXPO_PUBLIC_NAME, EXPO_PUBLIC_SCHEME, EXPO_PUBLIC_BUNDLE_ID, EXPO_PUBLIC_PACKAGE, and EXPO_PUBLIC_VERSION are derived in env.ts.
pnpm start
pnpm ios
pnpm android
pnpm webpnpm lint
pnpm lint:ts
pnpm lint:all
pnpm test
pnpm test:watch
pnpm test:ci
pnpm verify
pnpm install-maestro
pnpm e2e-test
pnpm doctor
pnpm knip:checkpnpm e2e-test currently targets the development app id and assumes Maestro is installed.
pnpm install-maestro uses a shell installer and may need a Bash-compatible environment.
development: local dev and internal development buildspreview: pre-release QA / preview buildsproduction: store-ready production builds
Helpers:
pnpm start:preview
pnpm start:production
pnpm ios:preview
pnpm ios:production
pnpm android:preview
pnpm android:productionsrc/app: Expo Router entry points and route filessrc/features: feature-first modules such as home, accounts, categories, transactions, scheduled transactions, stats, insights, import/export, settings, notifications, security, and AIsrc/components: shared app components and UI primitivessrc/lib: infrastructure for SQLite, storage, theming, i18n, utilities, and app-wide providerssrc/translations: translation resources
App startup happens in src/app/_layout.tsx, where the app initializes SQLite, runs migrations, sets up notifications, checks budget/upcoming-bill alerts, and mounts global providers.
- Financial records are stored locally in SQLite on the device.
- Preferences and lightweight persisted state are stored in MMKV.
- AI provider keys are configured in-app and stored locally in persisted state.
- AI requests are sent directly from the client to the selected provider.
.docs/setup.md.docs/architecture.md.docs/features.md.docs/testing.md.docs/release.mdAGENTS.md
This Project is based on Obytes starter
High-level roadmap (subject to change):
- Recommendations and Insights
- Improve overall UI/UX across the app
- Add richer transaction details (e.g. merchant)
