Grimoire (goniszewski/grimoire): a self-hosted bookmark manager with SQLite search
Bookmark manager for the wizards đź§™
At a glance
- What is it?
- Grimoire is a local-first bookmark manager for people who save technical resources. It runs a Bun daemon on 127.0.0.1:3210 with SQLite storage, and works without any AI provider. The search data around the name is mostly about games and occult books, not this project.
- Who is it for?
- Adopt Grimoire if you keep a personal library of technical links and want the database, the extraction pipeline and the search index on your own machine, with no AI provider required. Skip it if you need a supported Homebrew install, a stable v0.5 upgrade path, or a multi-user shared bookmark service; the README describes the migration tool as experimental and the formula as not yet validated.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Grimoire solves, and who it is actually for
Most bookmark tools assume a link is a title and a URL. That breaks down when you save a GitHub issue, a long StackOverflow thread, a PDF, or a conference talk with a transcript, and then try to find it six months later by remembering roughly what it argued. Grimoire targets that case specifically: people who accumulate technical resources and need retrieval by keyword or by meaning, not by folder.
The README states the audience plainly, describing a local-first bookmark manager for people who save technical resources and need to find them later. The topics list adds self-hosted, privacy, local-first and personal-knowledge-management. That combination points at a single technical user running the daemon on their own machine, not a team sharing a link board.
The name is a problem worth naming. Search data for the word grimoire is dominated by games (Warframe, Black Clover, Cookie Clicker, AQW), occult books and pronunciation questions. Someone searching for this project by name will land in that noise. Searching for the repository owner plus the project name is the more reliable route.
Two processes, one SQLite file, and a progressive ingestion pipeline
Grimoire splits into a frontend and a daemon. The README describes the frontend as React 18, Vite, TypeScript, Tailwind CSS and Radix UI primitives under `src/`, and the daemon as Bun, Hono and SQLite under `daemon/`, listening on `127.0.0.1:3210` by default. The daemon is the part that owns data; the frontend is a client of it.
Ingestion is the design decision worth understanding. The README lays out the pipeline as: save URL, enqueue a durable SQLite job, fetch public content, extract readable text and metadata, optionally enrich with an AI summary, tags and category, optionally create embeddings, then update search indexes. Two properties follow from that. First, the bookmark is visible immediately after save, so the UI never blocks on a slow fetch. Second, a pipeline failure leaves the bookmark usable and exposes retry and reprocess controls, which means a broken extraction is a recoverable state rather than a lost link.
Extraction is not generic. The README lists normal web pages, PDFs, GitHub repositories, GitHub issues, StackOverflow and StackExchange pages, and YouTube metadata and transcripts where available. Search runs on SQLite FTS5 keyword search, semantic embedding search, or a hybrid ranking mode. The keyword layer is available with no model at all; the semantic layer depends on an embeddings endpoint you supply.
Installing Grimoire with Docker and saving a first bookmark
The README gives three install paths. The source checkout is described as the recommended development path. The native installer copies daemon files, installs production dependencies, builds the frontend, writes a default config, registers the user service and starts the daemon. Homebrew is included as a formula but the README says public install, service lifecycle and data-preservation checks have not passed against release assets, and calls it not a supported installation path yet.
For a first look without touching your system, the Docker path is the shortest. Docker serves the built frontend and daemon API from one loopback-bound port.
docker compose up -d
curl http://127.0.0.1:3210/healthThe README says to open `http://127.0.0.1:3210` after that. The compose file binds the port to `127.0.0.1:3210:3210`, so the service is not exposed on your network by default, and it mounts a named volume at `/data` with `DATA_DIR=/data`. The healthcheck in the compose file curls `http://localhost:3210/health` every 30 seconds.
If you want to run from source instead, the README's development path is a clone followed by two installs, because the frontend and the daemon have separate dependency trees.
git clone https://github.com/goniszewski/grimoire.git
cd grimoire
npm install
cd daemon && bun install
cd ..Then the daemon and the frontend run in separate terminals. The README gives `npm run daemon:dev` for one and `npm run dev` for the other, with the Vite app at `http://127.0.0.1:8080` talking to the daemon at `http://127.0.0.1:3210`. Saving a URL is then done from the app, the API, MCP, the import flow, or a browser bookmarklet, all of which the README lists as supported entry points.
Where Grimoire gets in your way
The native installer is the biggest constraint. It writes to a fixed location: the README's data table puts the SQLite database at `~/.local/share/littleimp/littleimp.db`, with `.env`, `dist/`, `backups/`, `restore-rollbacks/` and `logs/` alongside it. Note the directory name is littleimp, not grimoire. There is no documented flag for relocating that tree, so if you want the library on a different disk you are looking at a symlink or the Docker volume instead.
The upgrade path from the old version is explicitly unfinished. The README calls `littleimp migrate` an experimental tool for v0.5 SQLite data and points at a migration guide before applying it. The legacy SvelteKit application is preserved on the `legacy/v0.x` branch, which tells you the rewrite did not preserve compatibility by default. Anyone with a real v0.5 library should read the guide and take a backup before running it.
Homebrew is documented but not validated. The README says the formula exists and that install, service lifecycle and data-preservation checks have not passed against release assets. Treating it as a working install is a mistake the README itself warns against.
Semantic search is optional in the strict sense. If you never configure an embeddings endpoint, you still get FTS5 keyword search. But the hybrid ranking mode and meaning-based retrieval depend on a provider, and the README lists OpenAI, Ollama, Anthropic, OpenRouter, DeepSeek international and custom OpenAI-compatible chat or embeddings endpoints. Running fully offline means running Ollama yourself, which the compose file includes as a commented-out service on `127.0.0.1:11434`.
Grimoire against a browser plus a read-it-later queue
The obvious alternative is what most people already have: browser bookmarks synced through a browser account, plus a read-it-later service for the queue. The difference is where the extraction and the index live. A browser keeps a title, a URL and a folder. A hosted read-it-later service keeps extracted text on its servers and gives you its search.
Grimoire moves both of those onto your machine. The README's data table is the clearest statement of the trade: bookmarks, content, tags, categories, jobs, notes, timeline events, backups and settings sit in SQLite and local files under `~/.local/share/littleimp/`. The cost is that you now operate a daemon, keep it running as a user service, and own the backups. The README documents a `backups/` directory for local snapshots and encrypted packages and a `restore-rollbacks/` directory for pre-restore copies, so the project expects restore to be a real operation you perform, not a theoretical one.
The second alternative is a general note-taking tool with a web clipper. Those tend to store richer prose but weaker link metadata, and they rarely give you FTS5 plus embeddings over the same corpus. Grimoire's bet is narrower and more specific: a link is the primary object, extraction is automatic, and the index is queryable three ways. If your saved material is mostly your own writing rather than other people's pages, that bet is pointed the wrong way for you.
Licence, maintenance and what an upgrade costs you
Grimoire is MIT licensed, stated in the README badge, in `package.json` as `"license": "MIT"`, and in the `LICENSE` file at the repository root. MIT is permissive: you can run, modify and redistribute it, including in commercial settings, provided the copyright notice and permission notice are preserved. That is a summary of the licence text, not legal advice; read `LICENSE` yourself if the distinction matters to your organisation.
On maintenance, the repository is not archived and the last push was on 2026-09-09, eight days before this writing. Releases show v1.1.0 on 2026-08-25, v1.0.1 on 2026-08-03 and v0.5.0 on 2025-02-21. The gap between v0.5.0 and the 1.x line is roughly eighteen months, which matches the README's description of the current application as a complete rewrite. The `package.json` version is 1.2.0 while the README badge reads release 1.2.0, so the next release is in flight.
Upgrade cost depends on your install path. The source installer has an explicit upgrade mode, and the README gives `./install.sh --upgrade` for upgrading from an unpacked source checkout or release archive. Uninstall preserves data by default via `./install.sh --uninstall`, and `--purge` is required to remove the library. Docker upgrades mean rebuilding the image and letting the `/data` volume persist. Neither path documents a schema-version check you can run before upgrading, so the practical precaution is the backup directory the daemon already maintains.
Editorial conclusion
Adopt Grimoire if you keep a personal library of technical links and want the database, the extraction pipeline and the search index on your own machine, with no AI provider required. Skip it if you need a supported Homebrew install, a stable v0.5 upgrade path, or a multi-user shared bookmark service; the README describes the migration tool as experimental and the formula as not yet validated. Before committing, run the Docker path, check that http://127.0.0.1:3210/health responds, and confirm where your data lands, since the native installer writes to ~/.local/share/littleimp/ rather than to a path you choose.
Frequently asked questions
What is Grimoire?
Grimoire is a local-first bookmark manager for people who save technical resources and need to find them later. It saves public http and https URLs, extracts readable content, and searches with SQLite FTS5 keyword search, semantic embedding search, or a hybrid ranking mode.
How do I set up Grimoire?
The README gives three paths: a source checkout with npm and bun installs followed by npm run daemon:dev and npm run dev, a native installer run as ./install.sh from the daemon directory, and Docker via docker compose up -d. Homebrew is included as a formula but the README states it is not a supported installation path yet.
Does Grimoire need an AI provider to work?
No. The README states it runs without AI providers, and optional providers include OpenAI, Ollama, Anthropic, OpenRouter, DeepSeek international and custom OpenAI-compatible chat or embeddings endpoints. Without one you still get FTS5 keyword search; semantic and hybrid search depend on an embeddings endpoint.
Where does Grimoire store my bookmarks?
For native installs the README puts user data under ~/.local/share/littleimp/, with the SQLite database at ~/.local/share/littleimp/littleimp.db and backups, logs and rollback copies in sibling directories. The Docker compose file mounts a named volume at /data with DATA_DIR=/data.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/goniszewski-grimoire)