vulpea · vulpea-ui · vulpea-journal · vulpea-para
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.
- Find and link -
vulpea-findandvulpea-insertsearch 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-doctorverifies directories, database, watchers and external tools.
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.
;; 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 noteNote: 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.
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.
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)- Emacs 29.1+
org-mode9.4.4+emacsql4.3.0+ (withemacsql-sqlite-builtin)s1.12+dash2.19+
For best performance, especially with large collections, install these external tools:
| Tool | Purpose | Impact | Install |
|---|---|---|---|
fd | Fast directory scanning | Lists files faster than find at startup and when polling | brew install fd / apt install fd-find / pacman -S fd |
fswatch | Reliable external change detection | Reports git/Dropbox/external changes as they happen | brew install fswatch / apt install fswatch / pacman -S fswatch |
rg | Unlinked mention search | Required by unlinked mentions, unused elsewhere | brew 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.
| Document | Description |
|---|---|
| Getting Started | Installation, first steps, basic concepts |
| User Guide | Daily usage, interactive commands, working with notes |
| Configuration | Indexing, sync and note creation options |
| API Reference | Programmatic usage, query functions, data structures |
| Journal Module | Daily notes with widgets and calendar integration (separate package) |
| Plugin Guide | Writing custom extractors for domain-specific data |
| Troubleshooting | Common issues and solutions |
| Comparison | How vulpea compares to org-roam, org-node and Supertag |
Companion packages that extend Vulpea, grouped by what they help with.
- 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.
- consult-vulpea - Consult integration for Vulpea. Provides
consult-vulpea-findandconsult-vulpea-insertwith 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.
- vulpea-auto-tag - Rules that add or remove tags on save (for example, keep a
todotag in sync with the presence of TODO keywords). - vulpea-agenda - Builds
org-agenda-filesfrom 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: vulpeadynamic blocks (by tags, todo, sort, limit) that refresh incrementally when the database changes.
- 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.
- 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.
- vulpea-field - Extension for easily adding new database fields. Compatible with v1 only - it builds on the org-roam-backed
vulpea-db-define-tablemechanism; in v2 use the plugin system instead.
Applications built on Vulpea:
- vino - Wine cellar management with rich metadata
Notable user configurations:
- d12frosted/environment - Personal configuration (13k+ notes), including the task management setup from the Task Management blog series
- jwiegley/dot-emacs
- chrisbarrett/emacs-d
- d4ncer/.emacs.d
- benthamite/dotfiles
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.
GPLv3
If you enjoy this project, you can support its development via GitHub Sponsors or Patreon.
