Skip to content

sudokoi/expense-buddy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

232 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Expense Buddy πŸ’°

Expense Buddy Logo

Get it on Google Play

Latest Release Build Status

A modern, cross-platform expense tracking app built with React Native and Expo. Track your daily expenses, visualize spending patterns, and sync your data securely to GitHub.

✨ Features

πŸ“Š Expense Management

  • Quick Entry: Add expenses with amount, category, date, and notes
  • Custom Categories: Create, edit, and reorder expense categories with custom colors and icons
  • Payment Methods: Track how you pay (Cash, UPI, Credit Card, Debit Card, Net Banking, Amazon Pay, etc.)
  • Saved Payment Instruments: Save your commonly used cards/UPI IDs with nicknames
    • Cards store only last 4 digits, UPI stores only last 3 digits
    • Expenses can reference a saved instrument by ID (CSV stays backward compatible)
  • Default Payment Method: Set a preferred payment method for faster entry
  • Full CRUD: Create, read, update, and delete expenses with ease
  • History View: Browse expenses organized by date with comprehensive filters (time, amount, search, categories, methods, instruments) and cross-tab synchronization with Analytics

πŸ“ˆ Analytics & Insights

  • Visual Charts: Bar charts showing daily spending patterns
  • Category Breakdown: See spending distribution across categories
  • Payment Method Analysis: Pie chart showing expense distribution by payment method
  • Multi-Currency Support: Analytics automatically groups expenses by currency; filter chips appear when multiple currencies are present
  • Advanced Filters: Filter by time period, categories, payment methods, saved instruments, amount range, and search text
  • Cross-Tab Filter Sync: Filters applied in History automatically apply to Analytics and vice versa
  • Instrument Breakdown: See spending per card/UPI nickname for selected payment methods
  • Time-based Analysis: Track expenses over days/weeks/months plus 3m / 6m / 1y windows
  • Amount Range Filtering: Filter expenses by minimum and maximum amounts
  • Search: Search across expense notes, categories, payment methods, and instrument nicknames

☁️ GitHub Sync

  • Secure Backup: Sync expenses to your private GitHub repository
  • Optional Settings Sync: Also sync non-sensitive app settings (like categories and saved payment instruments) via settings.json
    • Off by default; controlled by a toggle in Settings
    • GitHub token/repo configuration is never synced (stays on-device)
  • Daily File Organization: Expenses stored as expenses-YYYY-MM-DD.csv files (one file per day)
  • Git-Style Sync: Fetch-merge-push workflow prevents accidental data loss
    • Always fetches remote data before pushing
    • Merges local and remote changes by expense ID
    • Timestamp-based auto-resolution (newer version wins)
    • True conflict detection when edits happen within the same time window
  • Soft Delete: Expenses are marked with deletedAt timestamp instead of being removed, ensuring deletions sync correctly across devices
  • Smart Sync:
    • Auto-sync on app launch or after every change
    • Manual sync with upload/download controls
    • Incremental loading (last 7 days by default)
  • Dirty-Day Sync: Tracks which days changed and only re-hashes/uploads those daily files
  • Differential Sync: Only uploads changed files using content hashing for efficiency
  • Batched Commits: All file changes (uploads and deletions) are combined into a single atomic commit
  • Detailed Sync Feedback: Shows counts of expenses added, updated, and auto-resolved
  • Load More: Download older expenses 7 days at a time
  • Migration Support: Automatically migrates from old single-file format to daily files

🌍 Internationalization (i18n)

  • Multiple Languages: Full support for English (US, UK, IN), Hindi (ΰ€Ήΰ€Ώΰ€‚ΰ€¦ΰ₯€), and Japanese (ζ—₯本θͺž)
  • Dynamic Locale Loading: Only the active locale is bundled at startup for faster app launch; other locales load on-demand when selected
  • Locale Awareness:
    • Currency symbols adapt to your choice ($, Β£, β‚Ή)
    • Date formats match your region
  • Per-Transaction Currency: Track expenses in any currency (useful for travel)
  • Persistent Preferences: Remembers your language and default currency settings

🎨 User Experience

  • Cross-Platform: Works on iOS, Android, and Web
  • Dark Mode: Automatic theme switching with proper token-based styling
  • In-App Updates: Automatic update check on launch with non-intrusive banner notification
    • Dismissible notifications that remember your choice per version
    • Manual check available in Settings
    • Opens Play Store or GitHub releases based on install source
    • Shows a one-time β€œWhat’s New” changelog sheet on first launch after updating (when release notes exist)
  • Reusable UI Components: Consistent styling with ExpenseCard, AmountText, CategoryIcon, ScreenContainer, SectionHeader, and CategoryCard
  • Notifications: Toast messages for sync status and actions
  • Offline First: Works without internet, syncs when connected
  • First-Time Setup: Guided flow to download existing data
  • Performance Optimized: Virtualized lists + memoized components/handlers for smooth scrolling with large datasets

πŸš€ Getting Started

Prerequisites

  • Node.js 24.x or higher
  • Yarn 4.5.0 (included via packageManager)
  • Expo CLI
  • For iOS: Xcode and CocoaPods
  • For Android: Android Studio and SDK

Installation

  1. Clone the repository

    git clone https://github.com/sudokoi/expense-buddy.git
    cd expense-buddy
  2. Install dependencies

    yarn install
  3. Start the development server

    yarn start
  4. Run on your platform

    • iOS: yarn ios
    • Android: yarn android
    • Web: yarn web

πŸ“± Usage

Adding an Expense

  1. Tap the + tab
  2. Enter the amount
  3. Select a category
  4. Add a note (optional)
  5. Choose your payment method
  6. If you selected Credit/Debit/UPI, optionally select a saved instrument (or choose Others and enter digits)
  7. Choose the date
  8. Tap Add Expense

Managing Payment Instruments

  1. Go to the Settings tab
  2. Find Saved Instruments
  3. Tap Add to create a new card/UPI nickname
  4. Edit or remove instruments as needed (removals are soft-deletes so they sync correctly)

Setting Up GitHub Sync

  1. Sign in with GitHub (Android)

    • Go to the Settings tab β†’ GitHub Sync
    • Tap Sign in with GitHub
    • A browser will open and GitHub will show a short code
    • Confirm the code and authorize access
    • Back in the app, choose a personal repository you own
      • Organization repositories are not supported
      • Only repositories where you have write access are shown
    • Enter/select a branch (usually main)
    • Tap Save Config and then Test
  2. Use a token instead (Web / fallback)

    • Create a GitHub Personal Access Token (PAT)

      Option A: Fine-grained token (Recommended)

      • GitHub Settings β†’ Developer settings β†’ Personal access tokens β†’ Fine-grained tokens
      • Generate new token, select the sync repository
      • Permissions β†’ Repository permissions β†’ Contents: Read and write

      Option B: Classic token

      • GitHub Settings β†’ Developer settings β†’ Personal access tokens β†’ Tokens (classic)
      • Select the repo scope (required for private repositories)
    • In the app, enter:

      • Token
      • Repository in owner/repo format
      • Branch (usually main)
    • Tap Save Config and then Test

  3. Enable Auto-Sync (Optional)

    • Toggle Enable Auto-Sync
    • Choose timing:
      • On App Launch: Sync when app starts
      • On Every Change: Sync after add/edit/delete
    • Tap Save Auto-Sync Settings

Syncing Data

Smart Sync:

  • Tap Sync Now – uses git-style fetch-merge-push:
    • Fetches all remote expenses first
    • Merges with local data (newer timestamps win)
    • Prompts only for true conflicts (same expense edited on both sides within seconds)
    • Pushes merged result to remote

Auto-Sync:

  • Happens automatically based on your settings
  • Shows notifications when sync completes with detailed counts
  • Handles conflicts using timestamps (latest wins)

Loading More History

  • Scroll to bottom of History tab
  • Tap Load More to download 7 more days
  • Repeat to load older expenses

πŸ—οΈ Architecture

Expense Buddy follows a modular architecture with clear separation of concerns:

Tech Stack

  • Framework: React Native with Expo
  • Routing: Expo Router (file-based routing)
  • UI Library: Tamagui v1.144.0 (universal design system)
  • State Management: XState Store v3 (reactive stores) + XState v5 (sync state machine)
  • Storage: AsyncStorage + Expo SecureStore (with encryption utilities)
  • Charts: react-native-gifted-charts
  • Date Handling: date-fns
  • CSV Parsing: PapaParse
  • Testing: Jest + fast-check (property-based testing)
  • Error Handling: Centralized error utilities with classification
  • Type Safety: Comprehensive TypeScript with ServiceResult pattern

πŸ“š Architecture Documentation

For detailed architecture documentation including:

  • Store patterns and when to use each store type
  • Hook decomposition strategy
  • Performance optimization rationale
  • Single-pass filtering algorithm
  • Migration guides

See ARCHITECTURE.md

Project Structure

expense-buddy/
β”œβ”€β”€ app/                    # Expo Router pages
β”‚   β”œβ”€β”€ (tabs)/            # Tab navigation screens
β”‚   β”œβ”€β”€ day/[date].tsx     # Day detail view
β”‚   └── _layout.tsx        # Root layout
β”œβ”€β”€ components/            # Reusable components
β”‚   β”œβ”€β”€ analytics/        # Analytics chart components
β”‚   β”œβ”€β”€ ui/               # Styled UI components
β”‚   └── history/          # History-specific components
β”œβ”€β”€ hooks/                # React hooks
β”œβ”€β”€ stores/               # XState Store state management
β”œβ”€β”€ services/             # Business logic
β”œβ”€β”€ utils/                # Utility functions
β”œβ”€β”€ constants/            # App constants
β”œβ”€β”€ types/               # TypeScript types
└── locales/             # i18n translation files

For a complete component and service reference, see ARCHITECTURE.md. expense-buddy/ β”œβ”€β”€ app/ # Expo Router pages β”‚ β”œβ”€β”€ (tabs)/ # Tab navigation screens β”‚ β”‚ β”œβ”€β”€ index.tsx # Dashboard with charts β”‚ β”‚ β”œβ”€β”€ add.tsx # Add expense screen β”‚ β”‚ β”œβ”€β”€ history.tsx # Expense history with edit/delete β”‚ β”‚ β”œβ”€β”€ settings.tsx # Sync settings β”‚ β”‚ └── _layout.tsx # Tab layout β”‚ β”œβ”€β”€ day/[date].tsx # Day detail view β”‚ └── _layout.tsx # Root layout β”œβ”€β”€ components/ # Reusable components β”‚ β”œβ”€β”€ analytics/ # Analytics chart components β”‚ β”‚ β”œβ”€β”€ PaymentMethodPieChart.tsx # Payment method breakdown β”‚ β”‚ └── CollapsibleSection.tsx # Collapsible chart wrapper β”‚ β”œβ”€β”€ ui/ # Styled UI components β”‚ β”‚ β”œβ”€β”€ AmountText.tsx # Styled amount display β”‚ β”‚ β”œβ”€β”€ CategoryCard.tsx # Category selection card β”‚ β”‚ β”œβ”€β”€ CategoryIcon.tsx # Category icon with background β”‚ β”‚ β”œβ”€β”€ ExpenseCard.tsx # Expense list item card β”‚ β”‚ β”œβ”€β”€ ScreenContainer.tsx # Screen wrapper with padding β”‚ β”‚ β”œβ”€β”€ SectionHeader.tsx # Section title component β”‚ β”‚ β”œβ”€β”€ DefaultPaymentMethodSelector.tsx # Payment method preference β”‚ β”‚ β”œβ”€β”€ PaymentMethodCard.tsx # Payment method display card β”‚ β”‚ └── index.ts # Component exports β”‚ β”œβ”€β”€ Provider.tsx # App providers β”‚ β”œβ”€β”€ NotificationStack.tsx β”‚ └── SyncIndicator.tsx β”œβ”€β”€ hooks/ # React hooks β”‚ β”œβ”€β”€ use-sync-machine.ts # XState sync machine React hook β”‚ └── use-update-check.ts # In-app update check hook β”œβ”€β”€ stores/ # XState Store state management β”‚ β”œβ”€β”€ expense-store.ts # Expense data store β”‚ β”œβ”€β”€ settings-store.ts # App settings store β”‚ β”œβ”€β”€ notification-store.ts # Toast notifications store β”‚ β”œβ”€β”€ hooks.ts # Custom hooks (useExpenses, useSettings, etc.) β”‚ β”œβ”€β”€ store-provider.tsx # Store initialization provider β”‚ └── index.ts # Store exports β”‚ └── tests/ # Unit and property-based tests β”œβ”€β”€ services/ # Business logic β”‚ β”œβ”€β”€ sync-machine.ts # XState sync state machine (idle/fetching/merging/pushing/conflict/error) β”‚ β”œβ”€β”€ sync-manager.ts # Sync orchestration β”‚ β”œβ”€β”€ merge-engine.ts # Git-style merge logic (ID-based merge, timestamp resolution) β”‚ β”œβ”€β”€ github-sync.ts # GitHub API client (includes batch commit via Git Data API) β”‚ β”œβ”€β”€ csv-handler.ts # CSV import/export β”‚ β”œβ”€β”€ daily-file-manager.ts β”‚ β”œβ”€β”€ hash-storage.ts # Content hashing for differential sync β”‚ β”œβ”€β”€ change-tracker.ts # Record-level change tracking β”‚ β”œβ”€β”€ expense-storage.ts # Incremental local expense storage + migration β”‚ β”œβ”€β”€ payment-instruments.ts # Instrument utilities + validation β”‚ β”œβ”€β”€ payment-instruments-migration.ts # One-time linking migration for legacy expenses β”‚ β”œβ”€β”€ payment-instrument-merger.ts # Merge logic for syncing instruments β”‚ └── auto-sync-service.ts β”œβ”€β”€ constants/ # App constants β”‚ β”œβ”€β”€ categories.ts β”‚ β”œβ”€β”€ payment-methods.ts # Payment method definitions β”‚ └── payment-method-colors.ts # Chart colors for payment methods β”œβ”€β”€ tamagui.config.ts # Tamagui theme configuration with getColorValue helper └── types/ # TypeScript types β”œβ”€β”€ expense.ts └── payment-instrument.ts


## πŸ§ͺ Testing

The app includes comprehensive unit tests and property-based tests:

```bash
# Run all tests
yarn test

# Run tests in watch mode
yarn test:watch

Test Coverage

  • Unit Tests: Coverage for services, stores, and critical utilities
  • Property-Based Tests: fast-check properties validating merge/sync/store correctness
  • Test Files: Located in stores/__tests__/ and services/

πŸ”§ Configuration

Environment Variables

The app does not require user-provided environment variables.

The GitHub OAuth Client ID is configured in app.config.js (not a secret). For Expo Go / local dev you can override it via EXPO_PUBLIC_GITHUB_OAUTH_CLIENT_ID.

EAS Build Profiles

Defined in eas.json:

  • development: Development client with hot reload
  • preview: Internal distribution for testing
  • production: Production builds with auto-increment
  • internal: APK builds for direct distribution

πŸ“¦ Building

Development Build

yarn start

Production Build

# iOS
eas build --platform ios --profile production

# Android
eas build --platform android --profile production

# APK for testing
eas build --platform android --profile internal

Automated Releases

See .github/RELEASE.md for automated APK builds via GitHub Actions.

πŸ› Reporting Issues

Found a bug or have a feature request? We'd love to hear from you!

In-App Reporting:

  • Open the app and go to Settings
  • Scroll to APP INFORMATION
  • Tap Report an Issue
  • Choose between Bug Report or Feature Request

GitHub Issues:

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Make your changes and create a changeset:
    yarn changeset
  4. Commit your changes with the changeset:
    git add .
    git commit -m 'feat: add some amazing feature'
  5. Push to the branch (git push origin feature/AmazingFeature)
  6. Open a Pull Request

Changelog Management

This project uses Changesets for version management and automated changelog generation.

When contributing:

  • Run yarn changeset to document your changes
  • Select change type: patch (bug fixes), minor (new features), or major (breaking changes)
  • Write a clear description of what changed
  • Commit the generated changeset file with your PR

Automated releases:

  • When PRs with changesets are merged, a "Version Packages" PR is automatically created
  • Merging the Version PR triggers automatic tag creation
  • Tag push triggers APK build and GitHub Release creation
  • See .github/RELEASE.md for the full workflow

πŸ”’ Privacy Policy

Expense Buddy does not collect any data. All your expense data is stored locally on your device. The optional GitHub sync feature uses your own credentials and repository. Read the full Privacy Policy.

πŸ“ License

This project is open source and available under the AGPL-3.0 License.

πŸ™ Acknowledgments

πŸ“§ Contact

For questions or feedback, please open an issue on GitHub.


Made with ❀️ using React Native and Expo

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published

Contributors 3

  •  
  •  
  •