Skip to content
d12frostedPublic

About

Database layer for org-mode notes with async indexing, rich queries, backlink discovery, and external change detection. Scales to 100k+ notes.

Topics

Resources

Stars

469 stars

Watchers

9 watching

Forks

Latest commit

 

History

915 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vulpea

Banner

vulpea · vulpea-ui · vulpea-journal · vulpea-para

MELPA Release CI Sponsor

Vulpea turns a folder of org files into a note collection you can query. Any org entry with an ID is a note, a whole file or a single heading. Vulpea indexes them in its own SQLite database and, with autosync on, keeps it current even when git or Syncthing change files outside Emacs. You get commands for daily work with notes, and the same index as an API for building your own tools.

What You Get

  • Find and link - vulpea-find and vulpea-insert search titles, aliases and tags. Typing a title that doesn’t exist yet creates the note. Works with consult, embark and marginalia.
  • Headings are notes too - one file can hold a whole collection, and each heading is found, linked and queried on its own.
  • Backlinks and unlinked mentions - what links to this note, and what mentions it without a link.
  • Refactoring that keeps links intact - rename, move, split a heading out into its own file, or merge two notes. Links and their descriptions are updated to match.
  • Metadata and schemas - typed fields (numbers, dates, links to notes) in plain description lists. A schema declares what a kind of note should carry, flags violations and prompts you to fill in the missing fields.
  • Queries from Elisp - by tags, links, metadata, properties or any predicate.
  • Stays out of your way - file watchers feed a background queue, and a background worker process takes parsing off the main thread.
  • Extensible - extractor plugins index your own data into your own tables.
  • Checks its own setup - M-x vulpea-doctor verifies directories, database, watchers and external tools.

Design

Vulpea is a tool and a library at once. The commands above are built on the same public API you get: functions and the vulpea-note struct, never SQL tables, so the database can change without breaking your code. v2 replaced the whole backend that way. Core leaves out UI: sidebars, dashboards and journals live in companion packages (see Ecosystem). Vulpea and org-roam keep separate databases and can run side by side.

v1 was a layer over org-roam; v2 is a rewrite with its own database and indexing. Vulpea v2: a story of breaking up with org-roam tells why, and the Migration Guide covers upgrading. For how vulpea compares to org-roam, org-node and Supertag, see Comparison with Other Libraries.

Quick Start

;; 1. Configure (defaults to org-directory, so often not needed)
;; (setq vulpea-db-sync-directories '("~/org/"))

;; 2. Enable auto-sync (scans your notes in the background on start)
(vulpea-db-autosync-mode +1)

;; 3. Start using
;; M-x vulpea-find    - find and open notes
;; M-x vulpea-insert  - insert link to a note

Note: Only entries with an ID are indexed; M-x org-id-get-create adds one to the entry at point. One file can hold many notes: keep every swim session as a heading in swimming.org and each one is its own queryable note.

Best performance

Optional, but recommended once the basics work:

;; Parsing already runs in a background process by default; 'full
;; moves the database write there too, so saving a note - even a
;; 100MB one - blocks Emacs for about a millisecond (bench/README.md).
;; Bulk indexing (first run, rebuild) then uses one core instead of
;; two: it takes about as long as with the defaults, longer than with
;; t and the two settings below, but Emacs stays responsive throughout.
(setq vulpea-db-async-extraction 'full)

;; Skip org-mode-hook during indexing (fine unless you rely on
;; hook-based per-file setup).
(setq vulpea-db-parse-method 'single-temp-buffer)

;; Index only [[bracketed]] links. id: links are always bracketed,
;; so the note graph is unaffected; skips the expensive scan for
;; plain https://... links in prose.
(setq vulpea-db-index-plain-links nil)

Also install fd and fswatch - vulpea uses them for fast directory scans and external change detection. Then run M-x vulpea-doctor: it verifies the setup end to end and flags anything that quietly degrades performance (including extractor plugins that bypass the background worker). Details and trade-offs in configuration.

→ Full Getting Started Guide

Installation

Available on MELPA:

;; Using package.el (after adding MELPA to package-archives)
(package-install 'vulpea)

;; Using use-package
(use-package vulpea)

;; Using straight.el
(straight-use-package 'vulpea)

;; Using elpaca
(elpaca vulpea)

;; Using Doom Emacs - add to packages.el, then run 'doom sync'
(package! vulpea)

Doom users: see the Getting Started guide for a complete config.el example and a note about doom env (required for fswatch / fd detection).

Or clone manually:

git clone https://github.com/d12frosted/vulpea
(add-to-list 'load-path "/path/to/vulpea")
(require 'vulpea)

Dependencies

  • Emacs 29.1+
  • org-mode 9.4.4+
  • emacsql 4.3.0+ (with emacsql-sqlite-builtin)
  • s 1.12+
  • dash 2.19+

Optional (Strongly Recommended)

For best performance, especially with large collections, install these external tools:

ToolPurposeImpactInstall
fdFast directory scanningLists files faster than find at startup and when pollingbrew install fd / apt install fd-find / pacman -S fd
fswatchReliable external change detectionReports git/Dropbox/external changes as they happenbrew install fswatch / apt install fswatch / pacman -S fswatch
rgUnlinked mention searchRequired by unlinked mentions, unused elsewherebrew install ripgrep / apt install ripgrep / pacman -S ripgrep

Without fswatch, Vulpea falls back to polling: every few seconds it lists your directories and checks what changed. fd makes each listing faster than find (29ms vs 72ms for 14k notes, measured in bench/README.md). With fswatch, changes are reported as they happen and nothing is polled; install it on Linux too (distributions do not ship it by default), since polling checks every file from Emacs and gets expensive with large collections. Without rg, everything else keeps working and the unlinked mention search reports that ripgrep is missing.

Documentation

DocumentDescription
Getting StartedInstallation, first steps, basic concepts
User GuideDaily usage, interactive commands, working with notes
ConfigurationIndexing, sync and note creation options
API ReferenceProgrammatic usage, query functions, data structures
Journal ModuleDaily notes with widgets and calendar integration (separate package)
Plugin GuideWriting custom extractors for domain-specific data
TroubleshootingCommon issues and solutions
ComparisonHow vulpea compares to org-roam, org-node and Supertag

Ecosystem

Companion packages that extend Vulpea, grouped by what they help with.

Workflows and modules

  • vulpea-ui - Visual tools for your notes: a per-note sidebar of widgets (outline, backlinks, stats, and more) plus standalone views, with an easy API for your own widgets. Schemas get especially nice treatment here: a sidebar health widget that flags the current note’s violations with one-key fixes, and a collection-wide schema dashboard that shows how every note measures up to the schemas that apply to it.
  • vulpea-journal - Daily journaling with calendar integration. Creates one note per day with sidebar widgets for navigation, calendar view, and “on this day” from previous years.
  • vulpea-para - The PARA method (Projects, Areas, Resources, Archives) on top of Vulpea. A note’s role is read from its tags rather than its folder, with a self-updating agenda, capture that files itself, and views for areas, projects, and people.

Finding and inserting notes

  • consult-vulpea - Consult integration for Vulpea. Provides consult-vulpea-find and consult-vulpea-insert with live preview and consult’s narrowing features.
  • embark-vulpea - Embark actions and export for Vulpea notes.
  • citar-vulpea - Citar integration for Vulpea. Minor mode for managing bibliographic notes, linking citation library entries to Vulpea notes.
  • vulpea-capf - Completion-at-point for note titles and aliases: type a prefix in an Org buffer, pick a note, get an id: link.
  • org-semantic - Semantic and lexical search over a tree of Org notes (single static binary, no Python). Not Vulpea-specific, but composes with it: Vulpea indexes what a note is, org-semantic indexes what it says, and it keeps its index current from Vulpea’s file watchers via vulpea-db-updated-functions.

Tags, agenda, and dynamic content

  • vulpea-auto-tag - Rules that add or remove tags on save (for example, keep a todo tag in sync with the presence of TODO keywords).
  • vulpea-agenda - Builds org-agenda-files from notes carrying certain tags, so agenda follows your notes instead of a static file list. Pairs with vulpea-auto-tag.
  • vulpea-tag-links - Extractor plugin that turns selected tags into links to the notes they stand for, Logseq style.
  • vulpea-dblock - Declarative #+BEGIN: vulpea dynamic blocks (by tags, todo, sort, limit) that refresh incrementally when the database changes.

Graphs and analysis

  • vulpea-graph (neonmei) - Force-directed graph of your notes rendered as SVG inside an Emacs buffer; click a node to open the note.
  • vulpea-graph-ui - Live, org-roam-ui style graph in your browser, fed from the Vulpea database and updated as notes change; meta links become typed edges.
  • vulpea-graph (nicolas-graves) - Graph metrics over your notes (related notes, centrality, communities, lexical similarity, co-citations) with a Python engine and Elisp adapter; exposes the results as vulpea-mcp tools and vulpea-ui widgets.

Outside Emacs: LLMs, web, publishing

  • vulpea-mcp - MCP server in pure Elisp that exposes your notes to LLM tools (Claude Code, Claude Desktop): search, backlinks, tasks, corpus health checks, note creation via vulpea-create.
  • claude-orgmode - Claude Code plugin with a vulpea skill: create, search, link, and tag notes from Claude Code through emacsclient.
  • emacs-org-serve - Go service that reads the Vulpea database directly and serves an Org vault as JSON + PWA to mobile devices.
  • publicatorg - Make your Vulpea notes public.

Legacy

  • vulpea-field - Extension for easily adding new database fields. Compatible with v1 only - it builds on the org-roam-backed vulpea-db-define-table mechanism; in v2 use the plugin system instead.

Real-World Usage

Applications built on Vulpea:

  • vino - Wine cellar management with rich metadata

Notable user configurations:

Contributing

Contributions welcome. Architecture records the decisions behind v2 and why, and the Plugin Guide is the way in if you want to extend the database rather than change it.

License

GPLv3

Support

If you enjoy this project, you can support its development via GitHub Sponsors or Patreon.

About

Database layer for org-mode notes with async indexing, rich queries, backlink discovery, and external change detection. Scales to 100k+ notes.

Topics

Resources

Stars

469 stars

Watchers

9 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages