Bleeding edge emacs overlay [maintainer=@adisbladis]
Find a file
2025-12-02 05:43:08 -05:00
.github Bump actions/checkout from 4.2.2 to 6.0.0 2025-12-01 01:43:09 +13:00
overlays Work around broken tramp 2.8.0.4 tarball 2025-11-20 14:53:52 +13:00
repos Updated emacs 2025-12-02 09:31:51 +00:00
default.nix Fix non-flake overlay usage 2022-10-04 22:16:41 +08:00
elisp.nix Merge pull request #363 from cmm/extra-pkgs-for-default-init 2024-02-23 03:59:09 +13:00
flake.lock Updated flake inputs 2025-12-01 16:27:07 +00:00
flake.nix flake: bump nixpkgs-stable from 24.11 to 25.05 2025-09-25 10:40:01 +08:00
packreq.nix Shut up obsolescence warning 2024-02-04 18:10:04 -08:00
parse.nix Allow leaf to be used as an alternative to use-package.. 2020-12-27 11:24:17 +01:00
README.org Example comments help text updates. 2025-11-13 13:48:02 -07:00
update update: fixup repos 2023-12-24 01:19:10 +13:00

Emacs overlay for Nixpkgs

Quickstart

To get up and running quickly, add the following lines to your /etc/nixos/configuration.nix:

{config, pkgs, callPackage, ... }:
{
# ...

  services.emacs.package = pkgs.emacs-unstable;

  nixpkgs.overlays = [
    (import (builtins.fetchTarball {
      url = "https://github.com/nix-community/emacs-overlay/archive/master.tar.gz";
    }))
  ];

# ...
}

This configuration will enable this overlay, and define your system-wide emacs package as the emacs-unstable attribute it provides.

NOTE: Read the "Usage of the overlay" section below for further explanation of this configuration. This has the potential to break things, and will frequently trigger full source rebuilds of emacs.

If you want to enable daemon/server mode, add the following line to the same configuration:

services.emacs.enable = true;

It is recommended you read Nixpkgs and NixOS documentation on package overlays and overrides to familiarize yourself with the concepts:

Contents of the overlay

This overlay consists of two overlays: emacs and package.

You can use both of them as a whole overlay or only one of them.

package overlay

Elpa

Daily generations of Elpa.

Melpa / Melpa stable

Daily generations of Melpa & Melpa stable attribute sets.

EXWM & needed dependencies

This overlay provides fresh versions of EXWM and dependencies. This is updated daily.

emacs overlay

Emacs from Git and latest (including pre-releases)

This overlay also provides two versions (latest from git) for Emacs. These are updated daily.

These attributes are named emacs-git and emacs-unstable. emacs-git is built from the latest master branch and emacs-unstable is built from the latest tag.

Emacs from git is not guaranteed stable and may break your setup at any time, if it breaks you get to keep both pieces.

We also provide two attributes named emacs-git-nox and emacs-unstable-nox if you wish to have Emacs built without X dependencies.

Additionally, the two attributes emacs-git-pgtk and emacs-unstable-pgtk enable the pure GTK (PGTK) feature, which is incompatible with X and supports Wayland natively.

Extra library functionality

This overlay comes with extra functions to generate an Emacs closure from various types of dependency declaration. (These are abstractions on top of emacsWithPackages.)

For example, emacsWithPackagesFromUsePackage adds packages which are required in a user's config via use-package or leaf.

  { pkgs, ... }:
  {
    environment.systemPackages = [
      (pkgs.emacsWithPackagesFromUsePackage {
        # Your Emacs config as file or text. Org mode babel files are also
        # supported, but must be a file available at build-time and have a `.org`
        # file extension.
        # NB: Config files cannot contain unicode characters, since
        #     they're being parsed in nix, which lacks unicode
        #     support.
        # NB: Org-mode files must only specify `:tangle` values of `yes`, `no`, 
        #     `t`, or `nil` on src blocks, and must not include any configuration
        #     that changes the output `.el` name or location.
        # config = ./emacs.org;
        config = ./emacs.el;

        # Whether to include your config as a site-lisp default init file as well.
        # If not enabled, the config is only parsed to find the use-packages and
        # you're responsible for making the file available for Emacs to load at run-time.
        # Its value can also be a derivation like this if you want to do some
        # substitution:
        #   defaultInitFile = pkgs.substituteAll {
        #     name = "default.el";
        #     src = ./emacs.el;
        #     inherit (config.xdg) configHome dataHome;
        #   };
        # WARNING: Emacs restricts some settings to the user-specific files!
        # WARNING: Disabling this setting for org-mode configs is non-trivial!
        #          Emacs always resolves all symlinks to org-mode babel files before
        #          tangling, emacsWithPackagesFromUsePackage does not allow the tangled
        #          `.el` file name or location to be changed from the default, and
        #          your config must be a file path in the nix store for org-mode, which
        #          is read-only location a tangled `.el` file cannot be created in.
        defaultInitFile = true;

        # Package is optional, defaults to pkgs.emacs
        package = pkgs.emacs-git;

        # By default emacsWithPackagesFromUsePackage will only pull in
        # packages with `:ensure`, `:ensure t` or `:ensure <package name>`.
        # Setting `alwaysEnsure` to `true` emulates `use-package-always-ensure`
        # and pulls in all use-package references not explicitly disabled via
        # `:ensure nil` or `:disabled`.
        # Note that this is NOT recommended unless you've actually set
        # `use-package-always-ensure` to `t` in your config.
        alwaysEnsure = true;

        # This value changes what the assumed default is when an individual src
        # block does not specify the `:tangle` option. Only the `:tangle` option 
        # (or lack of) on individual src blocks is considered by 
        # emacsWithPackagesFromUsePackage and it normally defaults to `no`.
        # Note that this is NOT recommended unless you have something like
        # `#+PROPERTY: header-args:emacs-lisp :tangle yes` in your config,
        # which defaults `:tangle` to `yes` when not specified, and don't explicilty
        # set `:tangle yes` on individual src blocks.
        alwaysTangle = true;

        # Optionally provide extra packages not in the configuration file.
        # This can also include extra executables to be run by Emacs (linters,
        # language servers, formatters, etc)
        extraEmacsPackages = epkgs: [
          epkgs.cask
          pkgs.shellcheck
        ];

        # Optionally override derivations.
        override = final: prev: {
          weechat = prev.melpaPackages.weechat.overrideAttrs(old: {
            patches = [ ./weechat-el.patch ];
          });
        };
      })
    ];
  }

Similarly, emacsWithPackagesFromPackageRequires adds packages which are declared in a .el package file's Package-Requires header, which can be handy for CI purposes:

...
let
  emacsForCI = pkgs.emacsWithPackagesFromPackageRequires {
    packageElisp = builtins.readFile ./flycheck.el;
    extraEmacsPackages = epkgs: [
      epkgs.package-lint
    ];
  };
pkgs.mkShell {
  buildInputs = [ emacsForCI ];
}

Usage of the overlay

Latest master each rebuild

One way, and probably the most convenient way to pull in this overlay is by just fetching the tarball of latest master on rebuild.

This has side-effects if packages breaks or things like that you may want to be in control of which revision of the overlay you run.

Adding the overlay this way will extend your Emacs packages set to contain the latest EXWM and dependencies from their respective master and make the package emacs-git available. These of course change quite rapidly and will cause compilation time.

{
  nixpkgs.overlays = [
    (import (builtins.fetchTarball {
      url = "https://github.com/nix-community/emacs-overlay/archive/master.tar.gz";
    }))
  ];
}

Binary cache

You will want to use the nix-community binary cache. Where the overlay's build artefacts are pushed. See here for installation instructions.

Install directly from the overlay

The repository is meant to be used as an overlay as is explained above. Still, for experimental purposes, you might want to install a package directly from the overlay. For example, you can install emacs-git from a clone of this repository with the following command:

  nix-build --expr 'with (import <nixpkgs> { overlays = [ (import ./.) ]; }); emacs-git'

Community

Matrix chat