Emacs+ is → GNU Emacs formulae for macOS → Homebrew package manager. It offers a wide range of extra functionality over regular → 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 section for more information.
$ 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 masterFeel 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 → Development guidelines to have better understanding on how to contribute.
For recent changes, see → News.
- About
- Install
- Reinstall
- Build Configuration
- Emacs 31
- Emacs 30
- Emacs 29
- Features explained
- Community Features
- Icons
- Emacs configuration
- Known Issues
- Old versions
- FAQ
- Screenshots
- Acknowledgements
For fast installation without compilation (~1 min), pre-built binaries are available:
$ brew tap d12frosted/emacs-plus
$ brew install --cask emacs-plus-app # latest stable
$ brew install --cask emacs-plus-app@master # nightly from masterCask builds are self-contained applications with all dependencies bundled. They include:
- Native compilation (AOT)
xwidgets,tree-sitter,imagemagick,mailutilsEmacs.appandEmacs 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.
For custom build options (~30 min compile time):
$ brew tap d12frosted/emacs-plus
$ brew install emacs-plus [options] # latest stable
$ brew install emacs-plus@master [options] # from masterVersioned formulas are also available: emacs-plus@30, emacs-plus@29, etc.
By default, formulas build Cocoa Emacs with gnutls, librsvg, libxml2, tree-sitter, webp, native compilation, dynamic modules, and multicolor fonts. See → Options for customization.
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). jqis available (e.g.brew install jq).
Open terminal and type the following commands (don’t forget to use correct Emacs+ version, branch and options):
$ 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]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, #218 and #321.
In short, brew doesn’t really support options. They break time to time (brew#4793, brew#7397, brew#7498 to show a few).
$ brew uninstall emacs-plus
$ brew install emacs-plus [options]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:
- Path specified by
HOMEBREW_EMACS_PLUS_BUILD_CONFIGenvironment variable ~/.config/emacs-plus/build.yml~/.emacs-plus-build.yml(fallback)
# Example build.yml
icon: dragon-plus
patches:
- fix-window-role
inject_path: true| Option | Default | Description |
|---|---|---|
icon | none | Custom icon to apply. See → Icons Gallery for available icons. |
patches | none | (Formula only) List of community patches to apply. See → 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. |
For more customization options, see → Community Features for patches and → Icons for icon customization.
By default emacs-plus@31 uses the following features.
- Injected
PATHvalue from user shell (see separate section explaining this feature). - Cocoa version, e.g. builds
Emacs.appandEmacs Client.app(see → Emacs Client.app for details). - Unconditional support for
gnutls,librsvg,webp,libxml2,little-cms2,tree-sitterand dynamic modules. - Build with native compilation.
| 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 → 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.
Please note, that --with-no-titlebar is no longer needed in Emacs 30+, since the same can be achieved natively using this method.
By default emacs-plus@30 uses the following features.
- Injected
PATHvalue from user shell (see separate section explaining this feature). - Cocoa version, e.g. builds
Emacs.appandEmacs Client.app(see → Emacs Client.app for details). - Unconditional support for
gnutls,librsvg,webp,libxml2,little-cms2,tree-sitterand dynamic modules. - Build with native compilation.
| 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 → 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.
Please note, that --with-no-titlebar is no longer needed in Emacs 30, since the same can be achieved natively using this method.
By default emacs-plus@29 uses the following features.
- Injected
PATHvalue 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-sitterand dynamic modules.
| 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 |
--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 → 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.
Please note, that --with-no-titlebar is no longer needed in Emacs 29, since the same can be achieved natively using this method.
Ever find that a command works in your shell, but not in Emacs?
(c) @purcell
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, 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.
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 purcell/exec-path-from-shell.
To disable PATH injection for formula builds, set inject_path: false in your build.yml and reinstall:
inject_path: falseIn 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 #469.
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 purcell/exec-path-from-shell:
(exec-path-from-shell-initialize)If you need full PATH injection, use the formula instead of the cask.
Starting with emacs-plus@30 and emacs-plus@31, the following variables are defined in site-start.el:
| Variable | Description |
|---|---|
ns-emacs-plus-version | Major version of Emacs Plus (e.g., 30 or 31) |
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:
(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
)This is useful for conditionally enabling features that are specific to Emacs Plus, such as the ns-system-appearance-change-functions hook.
Starting with emacs-plus@30 and emacs-plus@31, 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.
| 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 |
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
After installation, create aliases in /Applications (the formula will suggest these commands in the caveats):
# Get the installation prefix (use emacs-plus@30 or emacs-plus@31)
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"}'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).
For more details, see → docs/emacs-client-app.md.
| square corners | round corners |
|---|---|
![]() | ![]() |
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 → yabai or → 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:
(setq frame-resize-pixelwise t)In emacs-plus@29, emacs-plus@30, and emacs-plus@31 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:
(add-to-list 'default-frame-alist '(undecorated . t))Add the following line instead for round corners:
(add-to-list 'default-frame-alist '(undecorated-round . t))Browse the web in Emacs as in modern browser.
The original → 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 → Veshboo’s emacs branch.
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.
(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)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 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.
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 → gccemacs documentation for more information.
Knows issues:
ld: library not found for -lSystem. This only happens on older versions ofgccinstalled by Homebrew. Please execute$ brew reinstall gcc libgccjitto resolve this issue.- Errors during compilation of your
init.el. Try running Emacs with-Qoption and give it some time to compile everything (maybe runM-xto force compilation) - you shall see buffer*Async-native-compile-log*in the list of buffers.
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:
# 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...Then rebuild Emacs:
$ brew reinstall emacs-plus@30For more information, see → Community Documentation.
Emacs+ supports 76 custom icons. To use one, add it to your ~/.config/emacs-plus/build.yml:
icon: dragon-plusSee the → Icons Gallery for all available icons with previews.
Note: The
--with-*-iconcommand line options are deprecated and will be removed on 2026-03-14. Please migrate to usingbuild.yml.
Emacs is a journey. And for some of you these projects might be inspiring.
Please checkout → Issues page for a list of all known issues. But here are several you should be aware of.
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.
$ brew install cask --ignore-dependenciesThis repository provides formulas for some older version. Feel free to use them, but they are not really supported anymore.
$ 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 26By default emacs-plus@28 uses the following features.
- Injected
PATHvalue from user shell (see separate section explaining this feature). - Cocoa version, e.g. builds
Emacs.app. - Unconditional support for
gnutls,librsvg,libxml2,little-cms2and dynamic modules.
| 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 → without titlebar |
--with-no-titlebar-and-round-corners | build → without titlebar, but round corners instead of square |
--with-x11 | build with x11 support (disables Cocoa, no Emacs.app bundle) |
--with-xwidgets | build → 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 |
Note: Options --with-x11 and --without-cocoa produce terminal/X11 builds that do not include Emacs.app. Icon options are ignored for these builds.
By default emacs-plus@27 uses the following features.
- Cocoa version, e.g. builds
Emacs.app. - Unconditional support for
gnutls,librsvg,libxml2,little-cms2and dynamic modules.
| 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 → without titlebar |
--with-x11 | build with x11 support (disables Cocoa, no Emacs.app bundle) |
--with-xwidgets | build → 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 comes without any available options due to → #195.
Development versions (emacs-plus@30, emacs-plus@31) are built from their respective branches (emacs-30, 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:
revision:
"30": 6abea4d98d1d964c68a78cb9b5321071da851654
"31": abc123def456789Then install or reinstall:
$ brew reinstall emacs-plus@30The build will display the pinned revision during installation.
Deprecated: Environment variables
HOMEBREW_EMACS_PLUS_30_REVISIONandHOMEBREW_EMACS_PLUS_31_REVISIONstill work but are deprecated. Please migrate tobuild.yml.
Many thanks to all → contributors, issue reporters and bottle providers (→ Sudarshan Wadkar, → Jon Hermansen).
If you enjoy this project, you can support its development via GitHub Sponsors or Patreon.




