13
14 Comments

How I designed an offline-first app. An outline.

https://dev.to/ash_grover/how-i-designed-an-offline-first-app-an-outline-45c
submitted this linkon July 1, 2021
  1. 2

    Interesting read! I'm building an offline-tolerant app in Electron that has similar needs like handling conflicts and syncing data from other devices. You should take a look at what the Hypercore Protocol team has been building. They very recently had a livestream demoing their new architecture syncing data between distributed datasets over a peer-to-peer network.

    1. 1

      Very interesting. It uses B-trees as their underlying data structure for the database and its peer-to-peer. I'm curious if its usable for normal use cases because users would have to upload/seed the data in order for it to work.

      I think for a chat application it can be usable, or for any app where multiple users are part of a group and want to share data in some way. For ex. a todo app with multiple users. The problem I see is that if any of those users are offline, I won't be able to get the data - such as any new todo items.

      I'll check out the stream, thanks for letting me know.

      1. 1

        I'm building a product that will be comparable to Google Drive and Gmail (but encrypted and private) with the tech and what I'm doing is seeding user's data for when they go offline.

        I'm also open-sourcing this code so more technical users could create their own seed peer on a server somewhere.

        1. 1

          I see, that sounds interesting. I checked out the website, I can see it competing with ProtonMail to some extent.

          All the best.

  2. 1

    Nice breakdown!

  3. 1

    Interesting article! I'm building a note-taking app that I want to be able to work offline as well, so I've been thinking about this a lot. I'm actually looking to merge note data instead of having a last write wins approach, so my offline strategy would probably need to be even more complex.

    I know your app isn't really built to handle multi-user collaboration, but I'm curious to hear more about your "push then pull" method of syncing data. If something was updated on the database by another user, then wouldn't it be possible to overwrite that data if you were pushing first? It seems like it's not based on the timestamp of when the action occurred, but based on when someone is connected to the Internet, so it's possible that a very old action could win the "last write wins."

    Maybe that's not something that would happen to most people, but it's very likely to happen if you go offline for long periods at a time (such as if you're hiking Mt. Everest ;)). It makes more sense (to me) to pull the data, do conflict resolution on the client, and then push the updated data.

    1. 1

      It all depends on tolerance levels. If you're okay with users overwriting data to some extent then it should work fine. As you mentioned, its not something that would happen to most people(not everyone is going to hike Mt. Everest :P) so I'd focus on something which can happen most of the time to most of the users.

      Even if multiple users were involved, I'd still go with LRW in my case as I don't expect multiple users to update text of the same card at the same time. If something does get overwritten, I'd expect that user knowingly made the change.

      Now, since you're working on a note taking app(it looks cool btw), LRW wouldn't work in your case, you'd need to merge your data as you said. If I was working on a note taking app, I would go with versioning of data as I mentioned in the blog post and show the users the history of the changes made. This in my opinion is easier to do than keeping track of individual changes in a note.

      Take a look at PouchDB/CouchDB, it handles syncing/versioning of data. Also take a look at Inkdrop app and the blog posts by the author. The author took a similar approach with PouchDB.

      1. 1

        Makes sense! There's value in going with a simple solution that goes 80-90% of the way there, rather than a more complicated one.

        I'm currently using Postgres, but PouchDB looks interesting. I do think however that it would be nice to decouple how data is synced from how it is stored. So data could be stored locally in something like IndexedDB, but online it could be stored anywhere according to the user's preferences (SQL, NoSQL, Dropbox, etc).

        My end goal is to build a "trustless" notes app where your data is stored offline and synced/backed up to the storage provider of your choice with end-to-end encryption -- but still a ways off from that!

        1. 1

          Oh cool. That's a good project to work on. You'll end up learning a lot of things. Definitely document your journey somewhere in a blog, would be super interesting to read.

          All the best.

  4. 1

    If you truly want to "keep-things-simple", you should actually create a desktop app. Then you'd truly understand the power of Desktop.

    1. 1

      Hey, that's what the post was about? I actually created an offline-first desktop app Brisqi and mobile app. I do mention in the blog post as well. The blog post is part of a series, where the first post is about what stack I used for creating my app and the lessons learned.

      1. 1

        This comment was deleted 5 years ago

        1. 1

          Oh I see. Thanks for the clarification. I see where you're coming from.

          I personally wouldn't disqualify JavaScript. I came from a C# background. For better part of my career, I've built enterprise desktop apps to server apps communicating over WCF and RPC. The fundamental concepts are pretty much the same across languages. This blog post I wrote can be applied to any language as it talks about design/architecture not any specific language.

          In regards to JavaScript, I wanted my app to be cross-platform. Electron provided the best eco-system and licensing of them all. JavaScript is a flexible language, and since I had the foundation of strongly typed language, I knew what pitfalls to avoid.

          1. 1

            The fundamental concepts are pretty much the same across languages.

            Except Javascript 😁I've done some JS work, and I've always hated it.

            I had the foundation of strongly typed language, I knew what pitfalls to avoid.

            Yeah, that definitely helps.

  5. 1

    Hey all, some people reached out to me asking how I designed my offline-first app. I've documented in this blog post how I approached it and the steps I took. Hope you find it insightful.

    Feel free to reach out to me if you have any questions.