Suppose, not entirely hypothetically , that you think you've found a bug in a package and that you have a complicated Emacs environment. If the package is a standard Emacs package, there's generally a simple way to reproduce the problem in a minimal setup; you can do '
emacs -Q
' to get a stock Emacs so you can file a nice clean bug report. However, this doesn't work by itself with a third party package that you've installed through
list-packages
. If you start '
emacs -Q
' and try to use the package, you'll probably get an error that your Emacs can't find it (and if it can find the package, you should be suspicious).
This is because the standard Emacs package system stores third partly packages under a directory tree, on Unix typically
~/.emacs.d/elpa
, with one directory per package, and none of these package directories are initially on your Emacs Lisp search path. Updating your Emacs Lisp search path is one of the jobs of package initialization; for some time, Emacs has normally done this automatically without needing to invoke anything explicitly (this is the
package-enable-at-startup
variable, cf ). The one exception is in 'emacs -q' and 'emacs -Q', where this isn't done.
Before I started writing this entry I would have confidently given you a recipe for setting up a single third party package. That recipe would have had a lot of old Emacs superstition mixed in, and I don't think it does what I think it did. Now, I'm not sure how you get a completely pure Emacs environment with one third party package and its dependencies, apart from setting up a completely new Emacs environment somehow.
The basics of doing package initialization in 'emacs -Q' appears to be to run either '
package-initialize
' or '
package-activate-all
'. The former is a command so can be run from M-x after Emacs has started; the latter is a function, so you need to use '
(package-activate-all)
' in, for example, the *scratch* buffer. Both of these will update the Emacs Lisp load path for all of your packages, but they also both appear to have the effect of activating autoloads for packages, so a lot of the time you don't need to '
require
' the package you're interested in. But this also means that the package you're interested in may detect the presence of other packages (through their autoloads) and automatically use them.
To get a completely minimal environment with just your specific package of interest, I believe that what you want to do is the following (in some convenient buffer, such as '
*scratch*
', and using some convenient way of evaluating this):
(package-initialize t) (package-activate 'flycheck)
Calling '
package-initialize
' this way "initializes" the package system but doesn't activate anything and doesn't add anything to
load-path
. Then calling '
package-activate
' will activate the package and anything it depends on, adding all of the relevant directories to
load-path
and setting up autoloads and so on. You may then want to "
(require 'flycheck)
" afterward to fully load the package.
There are two alternate ways that are perhaps somewhat better documented. First, you can add the specific package directory to
load-path
and then use '
require
' to specifically pull in the package. For example:
(add-to-list 'load-path "/u/cks/.emacs.d/elpa/flycheck-20260725.1853") (require 'flycheck)
If the package you're interested in has dependencies, you'll need to add them to the load path too. This has the advantage that you're not touching the package system in any way and you're not going to get surprised by something it does for you.
Another way to do this is to manipulate
package-load-list
before you trigger package activation in your 'emacs -Q':
(setq package-load-list '((flycheck t))) (package-initialize)
This appears to initialize only the package you're interested in. I assume that dependencies aren't automatically discovered and activated; if the package has dependencies, then that's up to you to add to
package-load-list
. Now that I've figured out how to use '
package-activate
', I suspect it's not worth bothering with this approach outside of unusual scenarios.
A corollary to all of this is that any time I make a bug report against a third party GNU Emacs package and say that I've reproduced it in a minimal setup, I'm going to write in the bug report how I set up that environment so that people can see if I was doing it wrong. (I thought I was being a little silly when I did it in my initial bug report , but it turns out not at all. Past me made a good call there.)
Sidebar: Startup superstition
My current .emacs has the following stanza:
(require 'package)
(add-to-list 'package-archives
'("melpa" . "https://melpa.org/packages/"))
(package-initialize)
Based on what I've read in the process of writing this entry, I believe the first and the last bits are now surplus in any modern Emacs and all I need to keep is the MELPA bit. This appears to be a GNU Emacs 27 change ( cf ).