Saving a large org file used to freeze Emacs for a second per megabyte. The synchronous path is now twice as fast, and an opt-in worker process takes the freeze down to about a millisecond - at any file size. Here's the whole story, including the parts where I was wrong.
The full schema arc in vulpea, shaped as much by reader feedback as by my own roadmap: the rules I deferred (conditional requirements, reference checks, composition) plus the UI that makes them livable - a per-note health widget, in-buffer linting, and a collection-wide dashboard with one-key fixes.
A tiny HTTP 429 on api.github.com quietly broke Emacs CI across most of my projects. Chasing it down revealed a community-wide trap with nix-based setup-emacs, led to a small throttle-proof GitHub Action, a fleet-wide CI cleanup, and a couple of long-standing bugs fixed in my ELPA mirror.
Everything in vulpea since v2.1 - the three roadmap features (unlinked mentions, schema validation, note renaming) plus a diagnostics command, a Doom module, bulk tag and metadata operations, and a security fix.
How I organize notes and tasks with PARA in vulpea - Projects, Areas, Resources, Archives - by deriving each note's bucket from metadata and queries instead of filing it into folders. PARA without GTD's weight.
Build a Pomodoro timer from scratch with vui.el. We start with a static clock, hit every wrong instinct around timers and state, and arrive at a clean async UI - the same example that surfaced real bugs in the library.
5% of a weekly limit looks fine — unless you're an hour into the week. Here's how I made the Claude Code statusline project rate-limit usage to the end of each window, so the color tracks pace, not just raw spend.
A study found AI users produced the same output while learning 17% less. The question isn't whether to use AI. It's whether you're expanding capability or outsourcing cognition.
How I took vulpea's autosync startup from 1.4 seconds to 8 milliseconds for 13,800 notes. A story of measuring first, then eliminating every blocking call from the startup path.
macOS 26 Tahoe introduces a new icon format with translucency and depth. Old icons get trapped in "icon jail" - a rounded square container. Automatic conversion looks terrible. Here's what it actually takes to make icons work.
How emacs-plus handles customisation without maintainer burnout. A three-tier system for patches and icons, 76 community icons, and a configuration file that works for both formula and cask installations.
After years of requests, emacs-plus finally offers pre-built binaries. Skip the 30-minute compile, get native compilation that just works, and never see "library not loaded" again. Here's how we made it happen.
How to get useful macOS notifications from Claude Code with proper icons, repository context, and workspace information using hooks and terminal-notifier.
How to implement nestable batch operations that defer side effects until the outermost batch completes. A pattern using depth counters and unwind-protect that's surprisingly tricky to get right.
When you erase and redraw a buffer, cursor position is lost. The naive fix—save and restore point—breaks when content changes. Here's how I arrived at a robust solution through iteration.
How React-style hooks work without explicit keys—using call order during execution to establish identity. A pattern that's non-obvious but elegant, implemented in Emacs Lisp.
Master use-ref, use-callback, and use-memo — the hooks that help you avoid unnecessary work. Learn when mutable references beat state, how stable callbacks prevent wasteful re-renders, and when memoisation pays off.
Master vui.el's four hooks - on-mount, on-unmount, use-effect, and use-async. Learn cleanup patterns, avoid stale closures with functional updates, and see runnable examples throughout.
Solve prop drilling with context and learn four composition patterns - container/presentational, compound components, render props, and slots - that keep complex UIs maintainable.
Build a working file browser from scratch in 8 incremental steps. Learn component decomposition, state lifting, callbacks, and the patterns that make UI code maintainable.
A 15-minute introduction to vui.el - React-style declarative UI components for Emacs. Learn props, state, composition, and the basics of building interactive interfaces without wrestling with buffers.
Complex Emacs UIs are hard - multiple data sources, cascading updates, cursor management. I tried three approaches to the same interface: imperative rendering, widget.el with zones, and declarative components. Here's what I learned, and why I ended up writing a 2.5k line library.
A bash script to track GitHub contributions across all branches — because the official graph lies, and I needed data to correlate commit frequency with questionable life choices.
A deep dive into Emacs's widget library: what it does well, where it falls apart, and a step-by-step case study of building a table widget with editable cells. Includes working code and hard-won lessons about state management, layout hacks, and cursor position preservation.
After using Nix, nix-darwin, and home-manager for 4-5 years, I've finally switched back to Homebrew and bash scripts. Here's why the promise of reproducibility didn't hold up on macOS, and how freeing 80GB of disk space was the final push I needed.
After fixing PATH injection on macOS 15, I'm dusting off a year-old feature: proper Finder integration for emacsclient. Using AppleScript instead of shell scripts, Emacs Client.app now handles file opening from Finder, drag-and-drop, and auto-starts the daemon. With one cosmetic icon issue that needs your help to solve.
A complete visual overhaul of this site—migrating from Hakyll to Next.js, adopting a brutalist + jRPG aesthetic, and upgrading to Tailwind CSS v4.1. Sharp corners, bold colors, and way less fighting with build systems.
Announcing Vulpea v0.3, with major performance improvements for note querying operations. The release introduces a materialised view table that provides a 4.5x speed boost for general queries, plus specialised query functions that can be up to 150x faster in certain scenarios. Whilst write operations take a small hit, the trade-off is worth it for large note collections. I've also added several…
Sharing how I improved PATH handling in Emacs+ to solve a common pain point. By injecting the user's PATH into Emacs.app during build, users now get the expected environment variables when launching Emacs from anywhere on macOS. This change also simplifies native-comp configuration and helps avoid common compilation issues. Whilst it's not as dynamic as exec-path-from-shell, it provides a solid…
Sharing some analytics insights from Emacs Plus and how they'll influence future maintenance. Looking at installation data, Emacs 28 is currently the most popular version, and features like native-comp and xwidgets are heavily used. I'm considering deprecating some rarely-used options whilst making it easier to enable simple build flags. For icons, modern-doom3, nobu417-big-sur, and spacemacs lead…
Sharing my yabai configuration for automatically setting up workspaces in macOS. I walk through how to create a consistent set of labelled spaces, clean up extras, and automatically move applications to specific workspaces on startup. Whilst tiling window managers aren't for everyone, this setup helps maintain an organised workflow by ensuring applications always land in their designated spaces.
A personal note explaining that whilst I'll be less available due to the war in Ukraine, projects will continue—though help from the community would be welcome.
Migrating from org-roam v1 to v2—covering mandatory IDs, improved note structure, enhanced database queries, and the transition from file-based to ID-based linking, with migration scripts and lessons learned.
Fixing PATH order issues when using Fish shell with nix-darwin—Fish's path_helper reimplementation was moving .nix-profile/bin to the end, preventing nix packages from overriding system binaries. Solution: preserve original PATH and restore order after Fish initialisation.
Streamlining task capture in org-roam with dedicated inbox files per machine, processing via org-agenda, and dynamic capture templates that automatically place one-on-one meeting notes in the correct person's file.
Comparing build tools for Emacs packages—makem.sh for simplicity, cask for robustness, and eldev for extensibility—with observations on when each tool suits different project needs.
Making Emacs configurations maintainable with eldev, straight.el, and structured init/lib/config files—achieving fast startup whilst enabling proper byte compilation, linting with elisp-lint, and testing with buttercup.
Handling network instability when updating Emacs packages with straight.el by creating a retry wrapper using advice-add to automatically retry failed network operations.
Building a utility function to select a person and view all related tasks in org-agenda, supporting aliases whilst leveraging vulpea's selection capabilities and org-mode's tag matching.
Optimizing org-roam agenda performance by dynamically tracking notes containing TODOs with a 'project' tag, reducing agenda loading from over 50 seconds to under 1 second.
Automating task tagging in org-roam with vulpea—when you mention someone in a task by linking to their note, the task automatically gets tagged with that person's name.
Managing person-related tasks in org-roam using filetags to automatically tag all tasks (like @FrodoBaggins), maintaining tag inheritance whilst moving to individual notes.
Fixing category display in org-roam agenda views by showing meaningful categories based on note titles instead of file IDs, with automatic extraction and formatting for clean, readable results.