DEV Community

Cover image for Grimoire: A Retrospective on Building Open Source Tools
Robert Goniszewski
Robert Goniszewski

Posted on

Grimoire: A Retrospective on Building Open Source Tools

I created Grimoire to solve a personal problem: most existing bookmark managers were either too basic, overloaded with features I didn’t need, or architecturally heavy for something that should be simple (I was picky). I wanted a simple yet intuitive, self-hosted solution that combined the user experience of a modern web app powered by a database that was easy to back up, inspect, and maintain - preferably SQLite.

What started as an excuse to learn SvelteKit turned into a short-lived but surprisingly popular open-source project. While Grimoire development is currently paused, the journey of building it forced me to confront real trade-offs around architecture, marketing, and technical debt.

The Evolution of the Stack

Grimoire's architecture was never set in stone; it evolved alongside my understanding of the problem.

Phase 1: The MVP (Velocity First)

In the beginning (v0.1.0), I prioritized speed to market. I have chosen PocketBase as a backend-as-a-service to handle authentication, the database, user management, and file storage - so I could focus on the frontend and business logic. This allowed me to ship a Dockerized MVP with categories, tags, and basic CRUD operations very quickly. Of course, it also had a dark mode.

It worked. It was simple. It attracted users.

But it also set the stage for future constraints and obstacles.

Phase 2: The Great Refactor (Architecture First)

As the feature set grew, I hit a wall. The tight coupling with PocketBase made custom logic difficult and the codebase felt unmaintainable in the long run.

In v0.4.0, I made the difficult decision to halt feature development and perform a massive refactor.

  • Decoupling: I moved away from the BaaS dependency to a custom backend.
  • Performance: I adopted Bun as the runtime and Drizzle ORM for type-safe database interactions.
  • Cleanup: I deleted nearly as much code as I wrote, streamlining the application logic.

This pivot resulted in a swifter UI, faster metadata processing, and a codebase that was significantly easier for contributors to navigate.

The lesson there was blunt: early convenience becomes long-term rigidity if you outgrow the abstraction.

Building an Ecosystem

I realized early on that a bookmark manager that requires manual copy-paste is already failing. Grimoire needed to meet users where they were starting: in the browser tab.

To solve this, I developed the Grimoire Companion, a browser extension for Chrome and Firefox.

That required:

  • designing an external API
  • documenting it with OpenAPI
  • implementing token-based authentication
  • handling secure communication between extension and instance

So I had to buckle up and start properly thinking about stability, security, and versioning.

The Challenges of In-Flight Changes

The most complex technical challenge was not building features, but taking responsibility for existing users' data. When I moved from PocketBase to Drizzle, I could not leave them behind.

I had to engineer a dedicated migration tool to map data from the old schema to the new structure, ensuring users preserved their bookmarks, tags, and stored images during the upgrade. Even though Grimoire was far from being stable and could easily lack backward compatibility, I have chosen to do it the proper way, even if that meant a lot more work to do.

Empathy for the user often manifests as robust migration scripts.

Current Status: On the Shelf

After a successful run and multiple releases, I decided that Grimoire achieved what I needed it to.

The landscape of web development moves fast. While the current iteration served its purpose well, I have paused active development to focus on other projects. I may resurrect Grimoire in the future, but with a fresh perspective, aiming for different goals and likely leveraging a more modern approach (perhaps focusing more heavily on AI-driven organization or local-first architectures).

For now, the code remains open and available as a reference implementation for a modern SvelteKit application.

Technical Stack Overview

  • Frontend: SvelteKit 2 (Vite 5)
  • Runtime: Bun
  • Database: Drizzle ORM (SQLite/PostgreSQL)
  • Auth: Lucia
  • Infrastructure: Docker Compose

Repo: github.com/goniszewski/grimoire

Top comments (0)