Librocco is an open-source inventory management system for bookshops. It is designed to be local-first: resilient under poor network conditions or power outages, to ensure that stock remains accurate across multiple terminals. This resilience allows day-to-day sales and inventory tasks to continue uninterrupted, even when a terminal drops offline or the internet doesn’t cooperate. It is currently used daily in an independent bookstore to manage 100k+ stock and transaction records. You can try it out with full production data at libroc.co/demo
Librocco is built on CR-SQLite, a CRDT extension to SQLite compiled to WebAssembly. This enables it to run directly in the browser, store data locally, and resolve conflicts across nodes automatically - without requiring user intervention.
Why have we been building it?
The project has its roots in a system first written over 15 years ago, while Silvio was working in one of the bookshops still using Librocco today. That early version was built with ext-gwt (JavaScript generated from Java). Codemyriad took on the re-build with the following goals:
- Modernise the existing system while preserving the lessons from its long use in real shops;
- Explore offline-first patterns and put CRDTs to the test in a practical domain
The work is supported by independent bookshops who care less about monetising the software itself than about using it to keep their businesses running smoothly. Our own motivation is similar: we want to see Librocco in use, proving that resilient, open-source tools can serve real communities.
Librocco is released under the GNU Affero licence.
What has it taught us?
1. Exploring options for local storage & sync
We started by building Librocco around CouchDB & PouchDB, but eventually decided this wasn’t a viable path forward. There were several reasons for this: CouchDB’s shortcomings; PouchDB’s outdated docs - but ultimately the deciding factor was sync performance. With full production data, two syncing nodes could take more than 30 minutes to communicate changes. This created challenges: how would we keep the UI responsive while this is ongoing, and how would we present conflict resolution in a way that doesn’t overwhelm after all of this time?
We researched alternatives and landed on CR-SQLite because:
- SQL felt familiar
- CRDT-based sync resolved conflicts without complex user-facing logic
- It can be used with or without a central coordinating server, making it a true peer-to-peer option.
We recently contributed to CR-SQLite, updating it to the latest WA-SQLite in order to enable OPFS as a storage layer. Since SQLite stores everything in a single file, this makes importing and exporting data from local storage far easier, and also improves our initial sync times significantly (more on this here).
2. Adopting Shape Up for project management
Basecamp’s Shape Up methodology resonated with us, especially the focus on “appetite” rather than estimates, and the idea that scope should be hammered to fit that appetite. For a small team with limited manpower, scope hammering is an essential discipline. It forces us to make hard calls to trim back our ambition and helps set boundaries to avoid getting lost in the weeds.
3. Choosing Svelte over React
Before Librocco, our team had worked solely with React. Rich Harris’s presentation on rethinking reactivity convinced us to make the switch to Svelte early on. The ecosystem was still young at the time, and we felt some of those growing pains, but over time libraries like Superforms and Melt UI, together with Daisy UI’s design system, have helped us build momentum - and build better, more accessible UIs.