Zachary Wood

January 7, 2025

Our journey to local-first

When I joined Constructable, I thought I had a pretty good idea about the technology stack we were going to use to build our product. Both John, our co-founder and CTO, and I had been working in Rails for years and had come to be true believers in the "Rails Way". Starting out on a new SaaS app, a Rails app built with the modern hypermedia focused stack seemed like a clear winner for delivering value quickly and building a solid foundation for our future.

Fortunately for us, we quickly learned the field of construction has some unique constraints that called all of our assumptions and plans into question. This led us on a journey where we discovered a brand new world that transformed the way we build products.

Understanding the Needs of Construction PMs

A central figure on any construction project is the Project Manager (PM). PMs use project management software to document the daily activity and progress of the project through Daily Logs. They also take potentially dozens of photos throughout the day, and might create Requests for Information (RFIs) if something comes up they need clarity on. As Molly, another of our co-founders, likes to say: “Everything comes back to the plans.” PMs also need to be able to view the project plans, which consist of hundreds of pages of PDF documents along with internal notes and markup relaying mission critical information about how the project is to be built.

What makes the PM different than your typical SaaS app user is they are on-site, working mostly from a phone or tablet, and often have spotty internet connections, or no internet connection at all. That means in order to build a usable product for construction project management, most, if not all, of the features need to work offline.

This realization led us to abandon the hypermedia focused approach of a vanilla Rails app and search for other options. If we were going to have any chance at building a full construction project management software with just three engineers, we couldn't afford to implement ad-hoc support for every feature that needed to work offline across web, Android, and iOS. We needed to solve this at foundational level.
 

Sync Engines

This journey led us to the up and coming world of local-first sync engines. With a sync engine, the application's data is synced locally to the user's device, and any actions they take are pushed to the server, processed, and then sent out to other clients who pull whatever data changed. This differs than a typical app where each page is a network trip that loads the data it needs, either in the form of HTML or as JSON.

A hidden benefit of this architecture is that offline support comes for free. Assuming the user syncs their data once ahead of time, they are able to fully use the app offline, and then any mutations they make while offline will be pushed once they regain connectivity. As John wrote about in his recent post, we also found this architecture results in a huge improvement in user experience. With a local-first app, the data is truly at your fingertips. Users are able to navigate through an entire project without seeing a single loading spinner. Users also love the real-time collaboration aspect thanks to the automatic synchronization of changes.

Not only is this approach better for users, we also found developing the app to be an unexpectedly great experience for us. With the entire data model available on the front-end, we don't have to spend anytime thinking about and building APIs to fetch data. As mentioned before, instant navigation and real-time collaboration came for free.

We explored many sync engine implementations but ultimately landed on Replicache. Thanks to Replicache, we were able to quickly build out our sync engine endpoints, database structure, authentication, mailers, background jobs and more using our back-end of choice, Rails, while we use a simple React SPA for our front-end.

Challenges

It hasn't been smooth sailing all the way - we've been gradually running into the various issues Linear faced as described in Tuomas Artman's fantastic talk, Scaling the Linear Sync Engine. As we grow larger, we'll certainly discover more issues and scaling challenges, but we're confident based the quality of Replicache and the success of a product like Linear that we'll be able to overcome any scaling challenges.

What's next

Up next I'll be sharing details and code to show what apps built using a sync engine look like. I'll also share how we built the sync endpoints in Rails so you can easily integrate Replicache into your own Rails apps.

Thanks for reading! Feel free to reach out if you have any questions about Constructable, sync engines, or anything else.
Zac ✌️


About Zachary Wood

Founding Engineer @ Constructable. Helping builders build.