BookBridge: Bidirectional Sync Between Obsidian and BookStack

BookBridge: Bidirectional Sync Between Obsidian and BookStack

Obsidian as a personal knowledge base, BookStack as a team wiki — two great tools that don’t talk to each other. Maintaining the same content in two places isn’t a workflow, it’s Sisyphean labor. The existing community plugins had weaknesses in HTML-to-Markdown conversion and no bidirectional sync. So we built our own.

BookBridge is an open-source Obsidian plugin that synchronizes bidirectionally between an Obsidian vault and a BookStack instance. Developed with Claude Code as a structured co-developer.

What BookBridge Solves

HTML→Markdown that actually works. BookStack stores HTML internally. Obsidian works with Markdown. Complex tables with colspan, BookStack callouts, code blocks with language tags, nested lists — all of this needs to be converted cleanly. Turndown with custom rules instead of hopes and prayers.

Images and attachments stored locally in the vault. Every image, every PDF is downloaded and stored locally. Markdown links point to local paths. Offline access to everything, no broken images when the server is unreachable.

Delete synchronization. Page deleted in BookStack? BookBridge detects it, asks for confirmation, and cleans up — or deliberately leaves it in place. The user decides, not the tool.

Conflict resolution. Same page modified on both sides? BookBridge shows a diff and lets the user choose. No “remote wins, tough luck.” If you lose data because a sync tool made a unilateral decision, you don’t have a sync tool — you have a liability.

Development with Claude Code as Co-Developer

BookBridge wasn’t created with a “write me a plugin” prompt. The foundation was a multi-agent setup in Claude Code with a clear structure.

Two Agents, Separate Perspectives

A plugin-dev agent for implementation — Obsidian API, TypeScript, BookStack REST, Turndown conversion. A qa-engineer for tests, security audits, and conversion quality. Two different perspectives on the same code, deliberately separated.

Four Skills as Workflow Stages

SkillFunction
/requirementsFeature specs with user stories and acceptance criteria
/buildImplementation with plan, approval, code, lint, and build
/qaTesting against acceptance criteria, Obsidian compliance, security
/releaseBuild GitHub release

Each phase has clear entry and exit criteria. No feature is considered done until lint, build, and tests are green.

QA as a Safety Net

Automated tests aren’t a nice-to-have when an AI writes code — they’re the safety net. The qa-engineer agent runs a structured 7-step test cycle after every implementation: unit tests with Vitest, Obsidian API compliance, security audit, and conversion quality.

Rules as Guardrails

Four rule files define what’s allowed: Obsidian API instead of Node.js access, requestUrl() instead of fetch(), TypeScript strict, no tokens in logs. The AI consistently adheres to them.

Feature Tracking

Every feature has an ID (FE-1, FE-2), every bug has a report (BUG-1, BUG-2). Conventional commits with references. Seems like overhead, but it pays off — at the latest when you look back three weeks later to understand why a particular decision was made.

Lessons Learned

No plan, no result. An AI doesn’t replace the development process. Architecture, conventions, feature specs, acceptance criteria — all of this must be in place before the first line of code is written. If you unleash an AI on a project without a clear plan, you get planless code.

The AI is only as good as the setup. Claude Code without rules, without agents, without clear architecture delivers generic output. Investing in structure and context pays off directly.

Human-in-the-loop. Every architectural decision, every new dependency, every destructive operation — the human decides. The AI suggests, the developer approves or corrects. It costs time, but saves the hours that would otherwise be spent debugging hallucinations.

The conversion was the real challenge. Not the sync, not the API integration. Getting HTML→Markdown→HTML roundtrip-stable — that was the work. Every Turndown custom rule has test cases, every edge case has a bug report. BookStack drawings can’t be meaningfully represented in Markdown? Then an honest fallback instead of broken output.

TypeScript strict is a feature. Especially with AI-generated code. No any, no @ts-ignore. When the compiler complains, that’s a safeguard — not an annoyance.

Who It’s For

For anyone who uses Obsidian as a personal knowledge base and works with BookStack in a team. Who doesn’t want to maintain two separate worlds. Who wants their images and attachments available offline. Who expects a sync that asks instead of guesses when conflicts arise.

And for anyone who wants to see how a structured AI setup can take a community plugin from idea to release — without a full-time development team.


BookBridge is open source on GitHub.


Translated with the help of Claude