https://github.com/d12frosted/homebrew-emacs-plus
Emacs Plus formulae for the Homebrew package manager
https://github.com/d12frosted/homebrew-emacs-plus
brew doom-emacs emacs homebrew spacemacs
Last synced: 20 days ago
JSON representation
Emacs Plus formulae for the Homebrew package manager
- Host: GitHub
- URL: https://github.com/d12frosted/homebrew-emacs-plus
- Owner: d12frosted
- License: mit
- Created: 2016-04-02T10:17:48.000Z (about 10 years ago)
- Default Branch: master
- Last Pushed: 2026-05-23T05:28:22.000Z (23 days ago)
- Last Synced: 2026-05-23T07:18:42.347Z (23 days ago)
- Topics: brew, doom-emacs, emacs, homebrew, spacemacs
- Language: Ruby
- Size: 134 MB
- Stars: 2,859
- Watchers: 43
- Forks: 210
- Open Issues: 7
-
Metadata Files:
- Readme: README.org
- Changelog: NEWS.org
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
#+begin_html
Emacs Plus
#+end_html
** About
Emacs+ is [[https://www.gnu.org/software/emacs/emacs.html][→ GNU Emacs]] formulae for macOS [[https://brew.sh][→ Homebrew]] package manager. It offers a wide range of extra functionality over regular [[https://formulae.brew.sh/formula/emacs#default][→ Emacs]] package. Emacs+ intent is to give the most of 'plus' stuff by default, leaving only controversial options as opt-in. Please refer to [[#options][→ Options]] section for more information.
#+begin_src bash
$ brew tap d12frosted/emacs-plus
# Pre-built binaries (fast, ~1 min)
$ brew install --cask emacs-plus-app # latest stable
$ brew install --cask emacs-plus-app@master # nightly from master
# Build from source (customizable, ~30 min)
$ brew install emacs-plus [options] # latest stable
$ brew install emacs-plus@master [options] # from master
#+end_src
#+begin_html
#+end_html
Feel free to open an issue or contact me via email if you face any issues, questions or feature requests. I love pull requests, so do send them. You might want to check [[docs/development-guidelines.org][→ Development guidelines]] to have better understanding on how to contribute.
For recent changes, see [[./NEWS.org][→ News]].
** Table of Contents :TOC_3:
- [[#about][About]]
- [[#install][Install]]
- [[#pre-built-binaries-cask][Pre-built binaries (Cask)]]
- [[#build-from-source-formula][Build from source (Formula)]]
- [[#installing-from-feature-branch][Installing from feature branch]]
- [[#reinstall][Reinstall]]
- [[#build-configuration][Build Configuration]]
- [[#available-options][Available Options]]
- [[#native-compilation-environment-cask][Native Compilation Environment (Cask)]]
- [[#emacs-32][Emacs 32]]
- [[#included][Included]]
- [[#options][Options]]
- [[#no-title-bar][No title bar]]
- [[#emacs-31][Emacs 31]]
- [[#included-1][Included]]
- [[#options-1][Options]]
- [[#no-title-bar-1][No title bar]]
- [[#emacs-30][Emacs 30]]
- [[#included-2][Included]]
- [[#options-2][Options]]
- [[#no-title-bar-2][No title bar]]
- [[#emacs-29][Emacs 29]]
- [[#included-3][Included]]
- [[#options-3][Options]]
- [[#no-title-bar-3][No title bar]]
- [[#features-explained][Features explained]]
- [[#injected-path][Injected PATH]]
- [[#detecting-emacs-plus][Detecting Emacs Plus]]
- [[#emacs-clientapp][Emacs Client.app]]
- [[#no-titlebar][No Titlebar]]
- [[#xwidgets-webkit][Xwidgets (webkit)]]
- [[#system-appearance-change][System appearance change]]
- [[#gccemacs][gccemacs]]
- [[#community-features][Community Features]]
- [[#icons][Icons]]
- [[#emacs-configuration][Emacs configuration]]
- [[#known-issues][Known Issues]]
- [[#emacs-dependency-in-other-formulas][=emacs= dependency in other formulas]]
- [[#old-versions][Old versions]]
- [[#emacs-28][Emacs 28]]
- [[#emacs-27][Emacs 27]]
- [[#emacs-26][Emacs 26]]
- [[#faq][FAQ]]
- [[#how-to-pin-a-specific-commit][How to pin a specific commit]]
- [[#screenshots][Screenshots]]
- [[#acknowledgements][Acknowledgements]]
** Install
*** Pre-built binaries (Cask)
For fast installation without compilation (~1 min), pre-built binaries are available:
#+begin_src bash
$ brew tap d12frosted/emacs-plus
$ brew install --cask emacs-plus-app # latest stable
$ brew install --cask emacs-plus-app@master # nightly from master
#+end_src
Cask builds are self-contained applications with all dependencies bundled. They include:
- Native compilation (AOT)
- =xwidgets=, =tree-sitter=, =mailutils=
- =Emacs.app= and =Emacs Client.app=
- Default Emacs icon
*Cask vs Formula:*
| Feature | Cask (=--cask=) | Formula |
|----------------------+------------------------+---------------------------|
| Install time | ~1 minute (download) | ~30 minutes (compile) |
| Custom build options | No | Yes (icons, patches, etc) |
| macOS versions | ARM64: 13+, Intel: 15+ | Any supported |
| Architectures | ARM64 and Intel | Any |
*Note:* Cask builds are architecture and macOS version specific. ARM64 has dedicated builds for Sonoma (14), Sequoia (15), and Tahoe (26); Ventura (13) users get the Sonoma build. Intel has a single Sequoia (15) build.
Use the *formula* if you need custom icons, patches, or specific build options. Use the *cask* for quick installation with sensible defaults.
*** Build from source (Formula)
For custom build options (~30 min compile time):
#+begin_src bash
$ brew tap d12frosted/emacs-plus
$ brew install emacs-plus [options] # latest stable
$ brew install emacs-plus@master [options] # from master
#+end_src
Versioned formulas are also available: =emacs-plus@32=, =emacs-plus@31=, =emacs-plus@30=, =emacs-plus@29=, etc. The =emacs-plus@master= alias points to the current development version (=emacs-plus@32=).
By default, formulas build Cocoa Emacs with =gnutls=, =librsvg=, =libxml2=, =tree-sitter=, =webp=, native compilation, dynamic modules, and multicolor fonts. See [[#options][→ Options]] for customization.
*** Installing from feature branch
Sometimes you might want to install from a feature branch. In that case you can switch the branch in the tap and install Emacs+ again.
Prerequisites are:
- Emacs+ is tapped (e.g. =brew tap d12frosted/emacs-plus=).
- =jq= is available (e.g. =brew install jq=).
Open terminal and type the following commands (don't forget to use correct Emacs+ version, branch and options):
#+begin_src bash
$ brew uninstall emacs-plus@29
$ cd $(brew tap-info --json d12frosted/emacs-plus@29 | jq -r '.[0].path') && git switch BRANCH
$ brew install emacs-plus@29 [OPTIONS]
#+end_src
** Reinstall
If you wish to reinstall =emacs-plus= with you should not use =reinstall= command of =brew= (not related to this formula, it's a general advice). Instead, you should =uninstall= a package and then =install= it with desired options.
Avoid =reinstall= even if you want to =reinstall= with the same set of options, otherwise you will likely to get compilation errors! For example, [[https://github.com/d12frosted/homebrew-emacs-plus/issues/218][#218]] and [[https://github.com/d12frosted/homebrew-emacs-plus/issues/321][#321]].
In short, =brew= doesn't really support options. They break time to time ([[https://github.com/Homebrew/brew/issues/4793][brew#4793]], [[https://github.com/Homebrew/brew/issues/7397][brew#7397]], [[https://github.com/Homebrew/brew/issues/7498][brew#7498]] to show a few).
#+BEGIN_SRC bash
$ brew uninstall emacs-plus
$ brew install emacs-plus [options]
#+END_SRC
** Build Configuration
Emacs+ can be configured using =~/.config/emacs-plus/build.yml=. This file controls options that are applied during installation (formula) or post-installation (cask).
The configuration file is searched in this order:
1. Path specified by =HOMEBREW_EMACS_PLUS_BUILD_CONFIG= environment variable
2. =~/.config/emacs-plus/build.yml=
3. =~/.emacs-plus-build.yml= (fallback)
#+begin_src yaml
# Example build.yml
icon: dragon-plus
patches:
- fix-window-role
inject_path: true
#+end_src
*** Available Options
| Option | Default | Description |
|---------------+---------+------------------------------------------------------------------------------|
| =icon= | /none/ | Custom icon to apply. See [[./community/icons/README.md][→ Icons Gallery]] for available icons. |
| =patches= | /none/ | (Formula only) List of community patches to apply. See [[#community-features][→ Community Features]]. |
| =revision= | /none/ | (Formula only) Pin Emacs source to a specific git revision. |
| =inject_path= | =true= | (Formula only) Inject user's PATH into Emacs.app. See [[#injected-path][→ Injected PATH]]. |
For more customization options, see [[#community-features][→ Community Features]] for patches and [[#icons][→ Icons]] for icon customization.
** Emacs 32
*** Included
By default =emacs-plus@32= uses the following features.
- Injected =PATH= value from user shell (see separate section explaining this feature).
- Cocoa version, e.g. builds =Emacs.app= and =Emacs Client.app= (see [[#emacs-clientapp][→ Emacs Client.app]] for details).
- Unconditional support for =gnutls=, =librsvg=, =webp=, =libxml2=, =little-cms2=, =tree-sitter= and dynamic modules.
- Build with native compilation.
*** Options
| Option | Description |
|---------------------------+---------------------------------------------------------------------------|
| =--with-compress-install= | build with compressed install optimization |
| =--with-dbus= | build with dbus support |
| =--with-debug= | build with debug symbols and debugger friendly optimizations |
| =--with-mailutils= | build with mailutils support |
| =--with-x11= | build with x11 support (disables Cocoa, no =Emacs.app= bundle) |
| =--with-xwidgets= | build [[#xwidgets-webkit][→ with xwidgets]] support |
| =--without-cocoa= | build a non-Cocoa version of Emacs (terminal only, no =Emacs.app= bundle) |
*Note:* Options =--with-x11= and =--without-cocoa= produce terminal/X11 builds that do not include =Emacs.app=. Icon options are ignored for these builds.
*** No title bar
Please note, that ~--with-no-titlebar~ is no longer needed in Emacs 30+, since the same can be achieved natively using [[https://github.com/d12frosted/homebrew-emacs-plus#emacs-29-1][this method]].
** Emacs 31
*** Included
By default =emacs-plus@31= uses the following features.
- Injected =PATH= value from user shell (see separate section explaining this feature).
- Cocoa version, e.g. builds =Emacs.app= and =Emacs Client.app= (see [[#emacs-clientapp][→ Emacs Client.app]] for details).
- Unconditional support for =gnutls=, =librsvg=, =webp=, =libxml2=, =little-cms2=, =tree-sitter= and dynamic modules.
- Build with native compilation.
*** Options
| Option | Description |
|---------------------------+---------------------------------------------------------------------------|
| =--with-compress-install= | build with compressed install optimization |
| =--with-dbus= | build with dbus support |
| =--with-debug= | build with debug symbols and debugger friendly optimizations |
| =--with-mailutils= | build with mailutils support |
| =--with-x11= | build with x11 support (disables Cocoa, no =Emacs.app= bundle) |
| =--with-xwidgets= | build [[#xwidgets-webkit][→ with xwidgets]] support |
| =--without-cocoa= | build a non-Cocoa version of Emacs (terminal only, no =Emacs.app= bundle) |
*Note:* Options =--with-x11= and =--without-cocoa= produce terminal/X11 builds that do not include =Emacs.app=. Icon options are ignored for these builds.
*** No title bar
Please note, that ~--with-no-titlebar~ is no longer needed in Emacs 30+, since the same can be achieved natively using [[https://github.com/d12frosted/homebrew-emacs-plus#emacs-29-1][this method]].
** Emacs 30
*** Included
By default =emacs-plus@30= uses the following features.
- Injected =PATH= value from user shell (see separate section explaining this feature).
- Cocoa version, e.g. builds =Emacs.app= and =Emacs Client.app= (see [[#emacs-clientapp][→ Emacs Client.app]] for details).
- Unconditional support for =gnutls=, =librsvg=, =webp=, =libxml2=, =little-cms2=, =tree-sitter= and dynamic modules.
- Build with native compilation.
*** Options
| Option | Description |
|---------------------------+---------------------------------------------------------------------------|
| =--with-compress-install= | build with compressed install optimization |
| =--with-ctags= | don't remove the ctags executable that Emacs provides |
| =--with-dbus= | build with dbus support |
| =--with-debug= | build with debug symbols and debugger friendly optimizations |
| =--with-imagemagick= | build with =imagemagick= support |
| =--with-mailutils= | build with mailutils support |
| =--with-x11= | build with x11 support (disables Cocoa, no =Emacs.app= bundle) |
| =--with-xwidgets= | build [[#xwidgets-webkit][→ with xwidgets]] support |
| =--without-cocoa= | build a non-Cocoa version of Emacs (terminal only, no =Emacs.app= bundle) |
*Note:* Options =--with-x11= and =--without-cocoa= produce terminal/X11 builds that do not include =Emacs.app=. Icon options are ignored for these builds.
*** No title bar
Please note, that ~--with-no-titlebar~ is no longer needed in Emacs 30, since the same can be achieved natively using [[https://github.com/d12frosted/homebrew-emacs-plus#emacs-29-1][this method]].
** Emacs 29
*** Included
By default =emacs-plus@29= uses the following features.
- Injected =PATH= value from user shell (see separate section explaining this feature).
- Cocoa version, e.g. builds =Emacs.app=.
- Unconditional support for =gnutls=, =librsvg=, =libxml2=, =little-cms2=, =tree-sitter= and dynamic modules.
*** Options
| Option | Description |
|---------------------------+------------------------------------------------------------------------------|
| =--with-compress-install= | build with compressed install optimization |
| =--with-ctags= | don't remove the ctags executable that Emacs provides |
| =--with-dbus= | build with dbus support |
| =--with-debug= | build with debug symbols and debugger friendly optimizations |
| =--with-imagemagick= | build with =imagemagick= support |
| =--with-mailutils= | build with mailutils support |
| =--with-native-comp= | build with native compilation aka [[#gccemacs][→ gccemacs]] |
| =--with-no-frame-refocus= | disables frame re-focus (ie. closing one frame does not refocus another one) |
| =--with-x11= | build with x11 support (disables Cocoa, no =Emacs.app= bundle) |
| =--with-xwidgets= | build [[#xwidgets-webkit][→ with xwidgets]] support |
| =--without-cocoa= | build a non-Cocoa version of Emacs (terminal only, no =Emacs.app= bundle) |
*Note:* Options =--with-x11= and =--without-cocoa= produce terminal/X11 builds that do not include =Emacs.app=. Icon options are ignored for these builds.
*** No title bar
Please note, that ~--with-no-titlebar~ is no longer needed in Emacs 29, since the same can be achieved natively using [[https://github.com/d12frosted/homebrew-emacs-plus#emacs-29-1][this method]].
** Features explained
*** Injected PATH
#+begin_quote
Ever find that a command works in your shell, but not in Emacs?
(c) @purcell
#+end_quote
In macOS applications are started in the login environment, meaning that all user defined environment variables are not available in application process. In the most cases it's not a big deal, but in Emacs it becomes a source of troubles as we want to use binaries from the non-standard locations (for example, those installed via package managers).
There is a wonderful solution to overcome this problem, [[https://github.com/purcell/exec-path-from-shell][purcell/exec-path-from-shell]]. As with any package that is not preinstalled with Emacs, you need to discover it first, and then install it. And while being a well known package and popular package (top 100 on MELPA), not everyone install it. In addition, with =native-comp= feature you might need it's functionality before any package is bootstrapped.
**** Formula builds
For formula builds (=brew install emacs-plus@30=), Emacs+ captures your shell's PATH at install time and injects it into =Emacs.app=. This makes your PATH available whenever you start =Emacs.app= from Finder, Dock, Spotlight, =open= command, or =launchd=. This solves a wide range of problems for GUI users without the need to use [[https://github.com/purcell/exec-path-from-shell][purcell/exec-path-from-shell]].
To disable PATH injection for formula builds, set =inject_path: false= in your =build.yml= and reinstall:
#+begin_src yaml
inject_path: false
#+end_src
In case you have a non-trivial setup relying on specific value of =PATH= inherited from current terminal session, it is advised to start Emacs using =/opt/homebrew/bin/emacs= instead of =open -n -a /path/to/Emacs.app=, because =open= messes around with =PATH= value even without Emacs+ injection. You can find more information in [[https://github.com/d12frosted/homebrew-emacs-plus/issues/469][#469]].
**** Cask builds
For cask builds (=brew install --cask emacs-plus-app=), PATH injection is *not available* due to a Homebrew limitation - cask postflight doesn't have access to the user's shell environment. Native compilation still works because =CC= and =LIBRARY_PATH= are injected.
Cask users who need their shell PATH in Emacs should use [[https://github.com/purcell/exec-path-from-shell][purcell/exec-path-from-shell]]:
#+begin_src elisp
(exec-path-from-shell-initialize)
#+end_src
If you need full PATH injection, use the formula instead of the cask.
*** Detecting Emacs Plus
Starting with =emacs-plus@30=, =emacs-plus@31=, and =emacs-plus@32=, the following variables are defined in =site-start.el=:
| Variable | Description |
|-------------------------------+-----------------------------------------------------------------------|
| =ns-emacs-plus-version= | Major version of Emacs Plus (e.g., 30, 31, or 32) |
| =ns-emacs-plus-injected-path= | Non-nil if user PATH was injected (formula with =inject_path: true=) |
This allows you to detect Emacs Plus and conditionally configure your init.el:
#+begin_src elisp
(when (bound-and-true-p ns-emacs-plus-version)
;; Emacs Plus specific configuration
)
;; Skip exec-path-from-shell if PATH was already injected
(unless (bound-and-true-p ns-emacs-plus-injected-path)
(exec-path-from-shell-initialize))
;; Check specific version
(when (and (bound-and-true-p ns-emacs-plus-version)
(>= ns-emacs-plus-version 31))
;; Emacs Plus 31+ specific
)
#+end_src
This is useful for conditionally enabling features that are specific to Emacs Plus, such as the =ns-system-appearance-change-functions= hook.
*** Emacs Client.app
Starting with =emacs-plus@30=, =emacs-plus@31=, and =emacs-plus@32=, the formula includes a companion application called =Emacs Client.app=. This application provides a user-friendly way to open files in Emacs from Finder, Spotlight, and other macOS applications.
**** When to use Emacs.app vs Emacs Client.app
| Application | Use Case |
|--------------------+---------------------------------------------------------------------------------------------------|
| *Emacs.app* | Launch Emacs directly, start a new Emacs session, or when you want full control over the instance |
| *Emacs Client.app* | Open files from Finder, set as default application for file types, quick file editing |
**** How it works
=Emacs Client.app= connects to an existing Emacs daemon (or starts one automatically) using =emacsclient=. This means:
- *Fast startup* - No need to launch a full Emacs instance for each file
- *Shared session* - All files opened via Emacs Client appear in the same Emacs session
- *Seamless integration* - Works with "Open With" in Finder, drag-and-drop, and can be set as the default application for text files
- *org-protocol support* - Handles =org-protocol://= URLs for org-capture, org-roam, and other integrations
**** Usage
After installation, create aliases in =/Applications= (the formula will suggest these commands in the caveats):
#+begin_src bash
# Get the installation prefix (use emacs-plus@30, emacs-plus@31, or emacs-plus@32)
PREFIX=$(brew --prefix emacs-plus@30)
# Create aliases in /Applications
osascript -e 'tell application "Finder" to make alias file to posix file "'$PREFIX'/Emacs.app" at posix file "/Applications" with properties {name:"Emacs.app"}'
osascript -e 'tell application "Finder" to make alias file to posix file "'$PREFIX'/Emacs Client.app" at posix file "/Applications" with properties {name:"Emacs Client.app"}'
#+end_src
You can then:
- Right-click files in Finder → "Open With" → "Emacs Client"
- Drag files onto the Emacs Client.app icon
- Set Emacs Client as the default application for specific file types
- Launch from Spotlight to create a new Emacs frame
- Use =org-protocol://= URLs from browser extensions (requires =(require 'org-protocol)= in your init file)
The implementation uses AppleScript to properly handle macOS AppleEvents, ensuring files opened from Finder are correctly passed to =emacsclient=. PATH injection works the same as in =Emacs.app= (see [[#injected-path][→ Injected PATH]]).
For more details, see [[file:docs/emacs-client-app.md][→ docs/emacs-client-app.md]].
*** No Titlebar
| square corners | round corners |
|---------------------------------------------------+--------------------------------------------------|
| [[/images/screenshot-no-titlebar-square-corners.png]] | [[/images/screenshot-no-titlebar-round-corners.png]] |
**** Emacs 28 and Emacs 27
This patch is enabled with the =--with-no-titlebar= option for =emacs-plus@27= and =emacs-plus@28=. It is meant for use with window tiling applications like [[https://github.com/koekeishiya/yabai][→ yabai]] or [[https://github.com/ianyh/Amethyst][→ amethyst]] so that the titlebar won't take up screen real estate.
Use =--with-no-titlebar-and-round-corners= option (instead of =--with-no-titlebar=), if you want to keep round corners (for example, to be consistent with other macOS applications).
If you see gaps between your emacs frames and other windows, try this:
#+BEGIN_SRC emacs-lisp
(setq frame-resize-pixelwise t)
#+END_SRC
**** Emacs 29+
In =emacs-plus@29=, =emacs-plus@30=, =emacs-plus@31=, and =emacs-plus@32= this option is not available anymore as you can achieve the same result using Emacs Lisp by adding the following line in your =early-init.el= file:
#+begin_src emacs-lisp
(add-to-list 'default-frame-alist '(undecorated . t))
#+end_src
Add the following line instead for round corners:
#+begin_src emacs-lisp
(add-to-list 'default-frame-alist '(undecorated-round . t))
#+end_src
*** Xwidgets (webkit)
Browse the web in Emacs as in modern browser.
The original [[https://www.emacswiki.org/emacs/EmacsXWidgets][→ Emacs xwidgets]] builds and works on macOS however must be used with X11 and hence not practical option on macOS. This version enables =xwidgets= on native macOS Cocoa via embedding a native webkit window.
More details can be seen here [[https://github.com/veshboo/emacs][→ Veshboo's emacs branch]].
*** System appearance change
This patch is enabled by default and can't be disabled. It adds a hook, =ns-system-appearance-change-functions=, that is called once the system appearance is changed. Functions added to this hook will be called with one argument, a symbol that is either =light= or =dark=. This mainly allows loading a different theme to better match the system appearance.
#+begin_src emacs-lisp
(defun my/apply-theme (appearance)
"Load theme, taking current system APPEARANCE into consideration."
(mapc #'disable-theme custom-enabled-themes)
(pcase appearance
('light (load-theme 'tango t))
('dark (load-theme 'tango-dark t))))
(add-hook 'ns-system-appearance-change-functions #'my/apply-theme)
#+end_src
Note that this hook is also run once when Emacs is initialized, so simply adding the above to your =init.el= will allow matching the system appearance upon startup. You can also determine what the current system appearance is by inspecting the value of the =ns-system-appearance= variable.
The hook is NOT run in TTY Emacs sessions.
*** gccemacs
#+begin_quote
gccemacs is a modified Emacs capable of compiling and running Emacs Lisp as native code in form of re-loadable elf files. As the name suggests this is achieved blending together Emacs and the gcc infrastructure.
[[https://akrl.sdf.org/gccemacs.html][→ Andrea Corallo]]
#+end_quote
While =gccemacs= gives performance boost in many scenarios, this feature is still experimental and might require time and effort from your side for it to work! Use at our own risk :)
Please see official [[https://akrl.sdf.org/gccemacs.html][→ gccemacs documentation]] for more information.
Knows issues:
- =ld: library not found for -lSystem=. This only happens on older versions of =gcc= installed by Homebrew. Please execute =$ brew reinstall gcc libgccjit= to resolve this issue.
- Errors during compilation of your =init.el=. Try running Emacs with =-Q= option and give it some time to compile everything (maybe run =M-x= to force compilation) - you shall see buffer =*Async-native-compile-log*= in the list of buffers.
** Community Features
Emacs+ supports custom patches and icons through a configuration file. This allows you to use community-maintained features or your own external resources.
Create =~/.config/emacs-plus/build.yml=:
#+begin_src yaml
# Use a community icon (see community/registry.json for available options)
icon: modern-purple-flat
# Use an external icon (requires SHA256 verification)
# icon:
# url: https://example.com/my-icon.icns
# sha256: abc123...
# Pin to a specific git revision (version-specific)
# revision:
# "30": abc123def456
# "31": 789abcdef123
# Apply community patches
# patches:
# - patch-name-from-registry
# - my-patch:
# url: https://example.com/external.patch
# sha256: abc123...
# - local-patch:
# url: ~/.config/emacs-plus/my-local.patch
# sha256: abc123...
#+end_src
Then rebuild Emacs:
#+begin_src bash
$ brew reinstall emacs-plus@30
#+end_src
For more information, see [[./community/README.md][→ Community Documentation]].
** Icons
Emacs+ supports 76 custom icons. To use one, add it to your =~/.config/emacs-plus/build.yml=:
#+begin_src yaml
icon: dragon-plus
#+end_src
See the [[./community/icons/README.md][→ Icons Gallery]] for all available icons with previews.
#+begin_quote
*Note*: The =--with-*-icon= command line options are deprecated and will be removed on 2026-03-14. Please migrate to using =build.yml=.
#+end_quote
** Emacs configuration
Emacs is a journey. And for some of you these projects might be inspiring.
- [[https://github.com/purcell/emacs.d][→ Steve Purcell's .emacs.d]]
- [[https://github.com/syl20bnr/spacemacs/][→ Spacemacs]]
- [[https://github.com/hlissner/doom-emacs][→ doom-emacs]]
- [[https://github.com/bbatsov/prelude][→ Prelude]]
- [[https://github.com/seagle0128/.emacs.d][→ Centuar Emacs]]
** Known Issues
Please checkout [[https://github.com/d12frosted/homebrew-emacs-plus/issues][→ Issues]] page for a list of all known issues. But here are several you should be aware of.
*** =emacs= dependency in other formulas
In some cases (like when installing =cask=) regular =emacs= package will be required. In such cases you might want to install all dependencies manually (except for =emacs=) and then install desired package with =--ignore-dependencies= option.
#+BEGIN_SRC bash
$ brew install cask --ignore-dependencies
#+END_SRC
** Old versions
This repository provides formulas for some older version. Feel free to use them, but they are not really supported anymore.
#+begin_src bash
$ brew tap d12frosted/emacs-plus
$ brew install emacs-plus@28 [options] # install Emacs 28
$ brew install emacs-plus@27 [options] # install Emacs 27
$ brew install emacs-plus@26 [options] # install Emacs 26
#+end_src
*** Emacs 28
**** Included
By default =emacs-plus@28= uses the following features.
- Injected =PATH= value from user shell (see separate section explaining this feature).
- Cocoa version, e.g. builds =Emacs.app=.
- Unconditional support for =gnutls=, =librsvg=, =libxml2=, =little-cms2= and dynamic modules.
**** Options
| Option | Description |
|----------------------------------------+------------------------------------------------------------------------------|
| =--with-ctags= | don't remove the ctags executable that Emacs provides |
| =--with-dbus= | build with dbus support |
| =--with-debug= | build with debug symbols and debugger friendly optimizations |
| =--with-mailutils= | build with mailutils support |
| =--with-no-frame-refocus= | disables frame re-focus (ie. closing one frame does not refocus another one) |
| =--with-no-titlebar= | build [[#no-titlebar][→ without titlebar]] |
| =--with-no-titlebar-and-round-corners= | build [[#no-titlebar][→ without titlebar]], but round corners instead of square |
| =--with-x11= | build with x11 support (disables Cocoa, no =Emacs.app= bundle) |
| =--with-xwidgets= | build [[#xwidgets-webkit][→ with xwidgets]] support |
| =--without-cocoa= | build a non-Cocoa version of Emacs (terminal only, no =Emacs.app= bundle) |
| =--with-imagemagick= | build with =imagemagick= support |
| =--HEAD= | build from =emacs-28= branch |
| =--with-native-comp= | build with native compilation aka [[#gccemacs][→ gccemacs]] |
| | |
*Note:* Options =--with-x11= and =--without-cocoa= produce terminal/X11 builds that do not include =Emacs.app=. Icon options are ignored for these builds.
*** Emacs 27
**** Included
By default =emacs-plus@27= uses the following features.
- Cocoa version, e.g. builds =Emacs.app=.
- Unconditional support for =gnutls=, =librsvg=, =libxml2=, =little-cms2= and dynamic modules.
**** Options
| Option | Description |
|---------------------------+------------------------------------------------------------------------------|
| =--with-ctags= | don't remove the ctags executable that Emacs provides |
| =--with-dbus= | build with dbus support |
| =--with-debug= | build with debug symbols and debugger friendly optimizations |
| =--with-mailutils= | build with mailutils support |
| =--with-no-frame-refocus= | disables frame re-focus (ie. closing one frame does not refocus another one) |
| =--with-no-titlebar= | build [[#no-titlebar][→ without titlebar]] |
| =--with-x11= | build with x11 support (disables Cocoa, no =Emacs.app= bundle) |
| =--with-xwidgets= | build [[#xwidgets-webkit][→ with xwidgets]] support |
| =--without-cocoa= | build a non-Cocoa version of Emacs (terminal only, no =Emacs.app= bundle) |
| =--without-imagemagick= | build without =imagemagick= support |
| =--HEAD= | build from =emacs-27= branch |
*Note:* Options =--with-x11= and =--without-cocoa= produce terminal/X11 builds that do not include =Emacs.app=. Icon options are ignored for these builds.
*** Emacs 26
Emacs 26 comes without any available options due to [[https://github.com/d12frosted/homebrew-emacs-plus/issues/195][→ #195]].
** FAQ
*** How to pin a specific commit
Development versions (=emacs-plus@31=, =emacs-plus@32=) are built from their respective branches (=emacs-31=, =master=). Ordinarily, =brew= will update to the latest commit during installation.
As development versions are less stable than official releases, you may want to pin a specific commit. The recommended way is to use =~/.config/emacs-plus/build.yml=:
#+begin_src yaml
revision:
"31": 6abea4d98d1d964c68a78cb9b5321071da851654
"32": abc123def456789
#+end_src
Then install or reinstall:
#+begin_src bash
$ brew reinstall emacs-plus@30
#+end_src
The build will display the pinned revision during installation.
#+begin_quote
*Deprecated*: Environment variables =HOMEBREW_EMACS_PLUS_30_REVISION= and =HOMEBREW_EMACS_PLUS_31_REVISION= still work but are deprecated. Please migrate to =build.yml=.
#+end_quote
** Screenshots
#+BEGIN_HTML
#+END_HTML
#+BEGIN_HTML
#+END_HTML
** Acknowledgements
Many thanks to all [[https://github.com/d12frosted/homebrew-emacs-plus/graphs/contributors][→ contributors]], issue reporters and bottle providers ([[https://github.com/wadkar][→ Sudarshan Wadkar]], [[https://github.com/jonhermansen][→ Jon Hermansen]]).
* Support
If you enjoy this project, you can support its development via [[https://github.com/sponsors/d12frosted][GitHub Sponsors]] or [[https://www.patreon.com/d12frosted][Patreon]].