My ~/.emacs
(which you can find on GitHub) file loads several different Emacs packages and I would like them to be automatically installed as soon as Emacs starts up, if they are not already installed. This way if I have to reinstall my Ubuntu 16.04 operating system again I will not have to install each package myself manually using M-x package-install
. Is there a way to write an ~/.emacs
file so that it will automatically install all loaded packages on startup? I would like this to be done with the minimum of lines as I have over ten different packages loaded so if I have to add extra lines for each individual package it will make my ~/.emacs
rather long.

- 707
- 5
- 23

- 623
- 10
- 19
-
4There are several ways, but you should use https://github.com/jwiegley/use-package – bertfred Nov 26 '16 at 14:28
-
Is it possible to load multiple packages in a single line with `use-package`, like I do on [line 61](https://github.com/fusion809/emacs/blob/735e055cd975235222c59f05d5869808efb39a94/.emacs#L61) of my .emacs file? – Josh Pinto Nov 26 '16 at 14:34
-
See `package-install-selected-packages` (requires Emacs 25.1). – politza Nov 26 '16 at 16:38
-
Out of curiosity, why is it such a desirable property to have all of your packages listed on a single line? The only reason that you give is to keep your `~/.emacs` file from getting "long." But if you are only loading a dozen packages, are you really concerned about the extra 11 lines in your config? – nispio Jul 04 '17 at 22:49
-
Well this was a few months ago so I don't remember my specific thinking but I suspect it was along the lines of trying to minimize how much work is required when I add or subtract a package from the list that is automatically installed. Didn't want multiple lines being added to the file for each separate package installed. – Josh Pinto Jul 05 '17 at 02:38
2 Answers
The easiest way is to install use-package
.
(package-initialize)
(require 'package)
(add-to-list 'package-archives
'("melpa" . "http://melpa.milkbox.net/packages/") t)
(dolist (package '(use-package))
(unless (package-installed-p package)
(package-install package)))
Then
(use-package paredit
:ensure t)
The :ensure t
is what ensures that the package is installed.
To just load ensure multiple packages are install
(dolist (package '(package-a package-b package-c))
(unless (package-installed-p package)
(package-install package))
(require package))))
-
-
-
Well my question is about multiple packages so please edit your answer so that it does just that, loads and if not present, automatically installs, multiple packages. – Josh Pinto Nov 26 '16 at 14:49
-
the dolist can be changed to '(use-package 'some-other-package), but no other configuration can be done. I would recommend having a line for each package with use-package. – njdan5691 Nov 26 '16 at 14:50
-
I have over ten different packages loaded so a more compact solution would be desirable. – Josh Pinto Nov 26 '16 at 14:51
-
-
OK, your answer is a little confusing. `paredit` isn't a package I have enabled in my `~/.emacs` so do I still add ` (use-package paredit :ensure t)` to my `~/.emacs` along with the other lines in your answer? PS. on line 3 of the final bit of your answer I think ya want `package-install pacakge` to be replaced with `package-install package`. – Josh Pinto Nov 26 '16 at 15:02
-
No, my example was clipped from my init.el so paredit is one of my packages installed, use should substitute your packages. `package-install` is how it is in my init.el, so not sure if `package-install-package` would work. – njdan5691 Nov 26 '16 at 15:06
-
I should substitute my packages (i.e., plural, or multiple packages) or package? I thought `use-package` was for a single package? – Josh Pinto Nov 26 '16 at 15:08
-
Ok, reread you last comment and you are correct there is a typo, there that needs correction. – njdan5691 Nov 26 '16 at 15:08
-
If you do now what one line for each package then don't use use-package. Use the last example in the original answer, and substitute your packages for package-a package-b package-c – njdan5691 Nov 26 '16 at 15:10
-
1@njdan5691 You should have something like `(unless package-archive-contents (package-refresh-contents))`, because unless you have somehow refreshed the package archives at least once, you can't install anything. Note that this hits the network. Also, the `(require 'package)` is redundant, because `package-initialize` is autoloaded. – jpkotta Dec 20 '17 at 18:17
package.el
keeps track of the packages you asked to install (as opposed to those that are auto-installed as dependencies) in the custom variable package-selected-packages
.
So if you copy your ~/.emacs
(in which Custom normally writes settings like that of package-selected-packages
) to another system, all you should need to do is M-x package-install-selected-packages
.
Of course, this doesn't automatically install the packages if they're absent, but I consider it a feature (I think it's a mistake for a program like Emacs to make network connections without an explicit request to do so). And it does save you the trouble of installing each package one by one.

- 26,154
- 3
- 46
- 84
-
Thanks. I just want to share my use case, which is different than that of the OP: I'm often transferring my dotfiles between machines (especially cloud, where they are created and killed all the time). The package directory is quite hefty, with elpy v-env and the kitchen sink, especially given old versions are not auto-trimmed, AFAIK. It's much easier to drop in a few small files and reinstall packages than carry them around. – kkm inactive - support strike May 18 '20 at 03:11
-
I forgot to mention one thing: `(package-refresh-contents)` needs to be invoked once before `(package-install-selected-packages)` when the local package directory is entirely missing, so that package distribution archive directories are cached first in subdirectories of its `archive/` directory. – kkm inactive - support strike May 18 '20 at 04:52