Bozhidar Batsov: Batppuccin: My Take on Catppuccin for Emacs

Wait 5 sec.

I promised I’d take a break from building Tree-sitter major modes, and I meantit. So what better way to relax than to build… color themes? Yeah, I know. Myidea of chilling is weird, but I genuinely enjoy working on random Emacs packages.Most of the time at least…Some BackgroundFor a very long time my go-to Emacs themes wereZenburn andSolarized – both of which Imaintain popular Emacs ports for. Zenburn was actually one of my very first opensource projects (created way back in 2010, when Emacs 24 was brand new). It servedme well for years.But at some point I got bored. You know the feeling – you’ve been staring at thesame color palette for so long that you stop seeing it. My experiments with othereditors (Helix, Zed, VS Code) introduced me toTokyo Night andCatppuccin, and they’ve been my dailydrivers since then.Eventually, I ended up creating my own Emacs ports of both. I’ve already publishedemacs-tokyo-themes,and I’ll write more about that one down the road. Today is all about Catppuccin.(and by this I totally mean Batppuccin!)Why Another Catppuccin Port?There’s already an official Catppuccin theme forEmacs, and it works. So why build anotherone? A few reasons.The official port registers a single catppuccin theme and switches betweenflavors (Mocha, Macchiato, Frappe, Latte) via a global variable and a reloadfunction. This is unusual by Emacs standards and breaks the normal load-themeworkflow – theme-switching packages like circadian.el need custom glue code towork with it. It also loads color definitions from an external file in a way thatfails when Emacs hasn’t marked the theme as safe yet, which means some userscan’t load the theme at all.Beyond the architecture, there are style guide issues.font-lock-variable-name-face is set to the default text color, making variablesinvisible. All outline-* levels use the same blue, so org-mode headings areflat. org-block forces green on all unstyled code. Several faces still shipwith #ff00ff magenta placeholder colors. And there’s no support for popularpackages like vertico, marginalia, transient, flycheck, or cider.I think some of this comes from the official port trying to match the structure ofthe Neovim version, which makes sense for their cross-editor tooling but doesn’tsit well with how Emacs does things.1Meet BatppuccinBatppuccin is my opinionated takeon Catppuccin for Emacs. The name is a play on my last name (Batsov) + Catppuccin.2I guess you can think of this as @bbatsov’s Catppuccin… or perhaps Batman’sCatppuccin?The key differences from the official port:Four proper themes. batppuccin-mocha, batppuccin-macchiato,batppuccin-frappe, and batppuccin-latte are all separate themes that workwith load-theme out of the box. No special reload dance needed.Faithful to the style guide. Mauve for keywords, green for strings, blue forfunctions, peach for constants, sky for operators, yellow for types, overlay2 forcomments, rosewater for the cursor. The rainbow heading cycle (red, peach, yellow,green, sapphire, lavender) makes org-mode and outline headings actuallydistinguishable.Broad face coverage. Built-in Emacs faces plus magit, vertico, corfu,marginalia, embark, orderless, consult, transient, flycheck, cider, company,doom-modeline, treemacs, web-mode, and more. No placeholder colors.Clean architecture. Shared infrastructure in batppuccin-themes.el, thinwrapper files for each flavor, color override mechanism, configurable headingscaling. The same pattern I use inzenburn-emacs andemacs-tokyo-night-theme.I didn’t really re-invent anything here - I just created a theme in a way I’mcomfortable with. I’m not going to bother with screenshots here – it looks like Catppuccin,because it is Catppuccin. There are small visual differences if you know whereto look (headings, variables, a few face tweaks), but most people wouldn’tnotice them side by side. If you’ve seen Catppuccin, you know what to expect.InstallationThe easiest way to install it right now:1234(use-package batppuccin-mocha-theme :vc (:url "https://github.com/bbatsov/batppuccin-emacs" :rev :newest) :config (load-theme 'batppuccin-mocha t))Replace mocha with macchiato, frappe, or latte for the other flavors. Youcan also switch interactively with M-x batppuccin-select.There Can Never Be Enough Theme PortsI remember when Solarized was the hot new thing and there were something like fivecompeting Emacs ports of it. People had strong opinions about which one got thecolors right, which one had better org-mode support, which one worked with theirfavorite completion framework. And that was fine! Different ports serve differentneeds and different tastes.The same applies here. The official Catppuccin port is perfectly usable for a lotof people. Batppuccin is for people who want something more idiomatic toEmacs, with broader face coverage and stricter adherence to the upstream styleguide. Both can coexist happily.I’ve said many times that for me the best aspect of Emacs is that you can tweakit infinitely to make it your own, so as far as I’m concerned having a themethat you’re the only user of is perfectly fine. That being said, I hopea few of you will appreciate my take on Catppuccin as well.Wrapping UpThis is an early release and there’s plenty of room for improvement. I’m surethere are faces I’ve missed, colors that could be tweaked, and packages thatdeserve better support. If you try it out and something looks off, please openan issue or send a PR.I’m also curious – what are your favorite Emacs themes these days? Still rockingZenburn? Converted to modus-themes? Something else entirely? I’d love to hearabout it.That’s all from me, folks! Keep hacking! The official port uses Catppuccin’s Whiskers template tool to generate the Elisp from a .tera template, which is cool for keeping ports in sync across editors but means the generated code doesn’t follow Emacs conventions. ↩︎ Naming is hard, but it should also be fun! Also – I’m a huge fan of Batman. ↩︎