Ivan Connections Logo image

Ivan Connections

Connecting Vision to Reality: Your AI Ally in App Innovation.

How I Rebuilt My Offline-First Budget App Using Go and C#

offline-first-featured-image

When I started building Budget Planner, I didn’t expect to release it to the Play Store. I mainly wanted to learn new skills and explore backend tech. But soon I realized that creating an offline-first budget app is not just a technical challenge — it’s essential for real-world usability.

Starting with Go: A Simple Online-Only Budget App

My first version of the app was online-only, built using Go and the Gin web framework. It was great for learning backend development — routing, middleware, database integration, and server hosting.

architecture diagram of online-only budget app in Go with server and cloud



One fun trick I built was middleware that delayed responses to suspicious paths, improving basic security. But there was one critical problem: no internet meant no app.

Why Offline-First Budget Apps Matter

Imagine needing to check your budget or log a quick expense while underground, in a rural area, or on airplane mode. If your app depends entirely on the cloud, you’re stuck waiting — or worse, unable to do anything at all.

That’s exactly why I chose to rebuild Budget Planner as an offline-first app. It needs to work anytime, anywhere — even with zero connection.

For a deeper dive into offline-first design principles, this article on offline-first development gives great insights.

The Big Decision: Going Offline-First

I made a tough choice to rebuild the entire app with offline functionality as the core feature, not an afterthought.

Since I had already built the user interface in .NET MAUI, it made perfect sense to switch the backend to C# and Entity Framework Core. This decision had several advantages: I was already comfortable with C#, and I could share the same data models and business logic between the frontend and backend parts of my app.
The transformation was remarkable. Now, when you open the app without internet:

  • All your past transactions are right there, instantly
  • You can add new expenses or income without any delays
  • The app quietly stores any new data on your device
  • Once you’re back online, everything syncs up automatically in the background

This change turned my app from a tech demo into something genuinely useful for everyday life.

From Simple to Sophisticated: The Architecture Journey

Moving from Go to Entity Framework Core was like upgrading from a bicycle to a car – more complex, but far more capable.

My original Go backend was beautifully simple: just 4 files that handled everything. But as I worked with C#, I wanted to build something that would grow well over time. I decided to implement CQRS (Command Query Responsibility Segregation) with MediatR, which are fancy terms for organizing code in a way that’s easy to understand and maintain.

This architectural choice transformed my simple backend into the most complex project I’d ever built. What started as 4 files became a system with over 20 different endpoints, each with its own dedicated files for handling requests, processing data, sending responses, and validating input.

Yes, it’s more complex now, but it’s also much more maintainable. When I need to fix a bug or add a new feature, I know exactly where to look. The local storage system in the app follows the same organized structure, which helps keep my thinking clear as I work on different parts of the project.

How the Magic Happens: My Sync Strategy

The synchronization between offline and online data might sound complicated, but I kept the approach straightforward:

  1. Every time you add a transaction, the app first tries to save it to the online database
  2. If the internet save fails (poor connection, server issues, etc.), the app stores the transaction locally on your device
  3. When you open the app later, it automatically checks for any unsynced data and tries to upload it again
  4. This process repeats until everything is safely stored online

It’s not the most sophisticated sync system in the world, but it’s reliable and works well for real-world usage patterns.

What I Learned: Go vs Entity Framework Core

After working extensively with both technologies, here’s my honest comparison:

Go with Gin Framework – The Good Parts:

  • Lightning-fast setup: You can have a working API in minutes
  • Minimal complexity: Everything fits in just a few files
  • Great for learning: The simplicity helps you understand web development fundamentals

Go with Gin Framework – The Challenges:

  • Hard to maintain as projects grow: What starts simple can become messy quickly
  • Files become monsters: Some of my Go files grew to over 500 lines, making them hard to navigate
  • Limited structure: Without careful planning, the codebase can become difficult to organize

Entity Framework Core – The Good Parts:

  • Excellent debugging tools: Finding and fixing problems is much easier
  • Familiar territory: Since I already knew C#, I could focus on solving problems instead of learning syntax
  • Professional architecture: CQRS and clean architecture patterns make the code feel robust and future-ready
  • Code reusability: I can share models and logic between different parts of the application

Entity Framework Core – The Challenges:

  • Lots of boilerplate code: You need to write more files and setup code to get the same functionality
  • Steeper learning curve: Understanding all the architectural patterns takes time and patience

What I’d Do Differently: Lessons for Next Time

If I could start this project over with everything I know now, I would build offline-first from day one. I’d use SQLite for local data storage right from the beginning, then add online synchronization as a secondary feature.

Starting with the online-only approach did teach me valuable lessons about Go and API development, but it wasn’t great for creating something people could actually use. In future projects, I’ll prioritize building genuinely useful applications first, then use them as platforms for experimenting with new technologies and techniques.

The Bigger Picture: Building Apps That Matter

This Budget Planner journey taught me more than I expected when I started. I began wanting to learn Go, and ended up creating the most sophisticated C# backend I’ve ever built. But more importantly, I learned the difference between building something that works as a technical demo versus building something that actually solves real problems for real people.

The app now works reliably whether you’re connected to Wi-Fi, using mobile data, or completely offline. Users can trust it to be there when they need it, which is what any good tool should do.

Want help getting started with your own offline-capable app?

Drop me a message at here ← where I build mobile and web apps that actually work for real users.