← Jon Jampen Case Study 01

Open source TypeScript · 2024 – now

Handwritten notes, inside a plain-text vault.

An Obsidian plugin that makes Xournal++ notebooks feel native: draw by hand, and the PDF shows up in your notes the moment you save. I built it for my own maths lectures. Now thousands of people use it, and I maintain it.

role
Author & maintainer
timeline
May 2024 – now
stack
TypeScript, Obsidian API, GitHub Actions
links
source
plugin page

Notebooks show up as PDFs labelled X++. One click opens the original in Xournal++.

11k+downloads
78GitHub stars
21releases since May 2024
6contributors

01Problem

Maths lectures need handwriting. My notes live in Obsidian, which is plain Markdown files on disk. I'm on Linux, so the usual tablet note apps were out. Xournal++ is great for writing by hand and annotating PDFs, but Obsidian ignores its .xopp files completely. I couldn't link them, preview them or embed them.

I wanted handwritten pages to be first-class notes, not attachments I had to export by hand.

So my notes ended up split in two: typed notes in the vault, handwriting in a separate folder, and a manual "export to PDF" step that I kept forgetting.

02How it works

The core idea is a corresponding PDF: every Xournal++ notebook gets a PDF with the same name, in the same folder. Obsidian already knows how to render PDFs, so the plugin's job is to keep that pair in sync. It hides the plumbing and adds the actions you'd expect.

Flow: a .xopp file changes, the plugin calls Xournal++ to export it, and Obsidian renders the PDF with an edit action. lecture.xopp you draw & save plugin watch vault on modify → .xopp? export via Xournal++ writes lecture.pdf next to it Obsidian embed · link · X++ label "edit in Xournal++" opens the source again

The PDF is just a rendered copy. The .xopp file stays the source of truth.

What you get in Obsidian

  • Auto-export: each time a notebook changes, its PDF is regenerated.
  • Create new notebooks from the ribbon, file explorer, folder menu or command palette.
  • Edit in Xournal++ from the PDF preview, the file explorer's X++ label, or a command.
  • Rename and delete the notebook and its PDF together, so the pair never drifts apart.

03Decisions

Most of the design came down to staying out of the way of two apps I don't control.

Render with what's already there

No custom handwriting viewer. Obsidian already renders PDFs well, so the plugin only produces PDFs and adds actions around them.

One file in the explorer, not two

The PDF is shown with an X++ label rather than listing both files. That way the vault reads like one note per notebook.

Paired file operations

Rename and delete go through the plugin, so a notebook never ends up without its PDF, or with a stale one.

Beta channel before releases

Bigger changes go out as betas first. Early adopters catch platform-specific problems before everyone else updates.

04Maintaining it

After the first release, the work changed. It became less about writing features and more about running a small open-source project: triaging issues, reviewing outside pull requests, writing docs and shipping regularly without breaking people's vaults.

# .github/workflows/ci.yml — on every push & PR
npm run lint          ✓ eslint
npm run format:check  ✓ prettier
npm run test          ✓ unit tests
npm run build         ✓ plugin bundle
# release.yml — tag → build → GitHub release
# deploy-docs.yml — wiki → docs site

A contribution can only be merged once lint, formatting, tests and the build all pass.

  1. 1.0.0May 2024

    First public release in the Obsidian community plugin directory.

  2. 1.0.1 – 1.0.11May 2024 – Jan 2025

    Eleven patch releases, mostly driven by issues from new users.

  3. 1.1.0Apr 2025

    First minor release. Afterwards, a beta channel for testing changes early.

  4. 1.2.0-beta.1Dec 2025

    A longer beta period for the next feature release.

  5. 1.2.1Aug 2026

    Current version. 21 releases in total.

05Outcome

Something I built for one lecture now has over 11,000 downloads, a Discord community, a docs site and contributors who aren't me. 17 community pull requests have been merged so far.

It's also where I learned what I enjoy most: the work around the code. That means CI that makes reviewing a pull request from a stranger safe, releases that are boring, and docs good enough that the same question doesn't come up twice.

Next Fatigue Diary →An energy tracker for people with chronic fatigue, tested with therapists and patients.