Getting Started with Use-Package

25 Aug 2015 Gregory J. Stein
Tags Emacs

Of all the packages I use to enhance my productivity in emacs, use-package is perhaps the most useful. With it, I can automatically download and install other packages from the emacs package databases when it detects they’re missing. Since I’m constantly switching computers, virtual machines, and operating systems, having this functionality is essential for making sure I don’t miss a beat when I’m starting from scratch; I simply clone the emacs config files from my GitHub repository and open emacs and I’m almost immediately ready to go.

This short guide shows how to ensure that use-package also automatically installs, and how to get the most out of the use-package features.

Auto-Installing Use-Package

As I’m sure you may have realized by now, use-package is unable to install itself, which means that I do need a small bit of code which can pull the package from MELPA, an emacs package repository, and install it. Include the following code at the top of your init.el file:

Install Use-Package Lisp
(require 'package)
(setq package-enable-at-startup nil)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
(add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/"))
(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/"))
(package-initialize)

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

(eval-when-compile
  (require 'use-package))
(require 'diminish)
(require 'bind-key)

You can also find this code here on our GitHub. I won’t go into the details, though much of the code should be self-explanatory.

Reducing Emacs Load Times

One of the best things about relying on use-package is the :defer t option, which will prevent the package from loading until it detects it’s needed. This means that, by only loading a couple of packages at startup, opening emacs should only take a fraction of the time it used to take, assuming you loaded a great many packages which were not immediately necessary. I simply did not realize how much of an improvement this would be until, I lowered my load time from roughly four seconds to under one second, and could begin editing files from the command line using emacs without skipping a beat.

More details on how to use this can be found on the Use-Package GitHub page.

There is however, one potential downside to abusing this feature. Most commonly, the sorts of issues that I will run into are that I’ve set a package to defer loading, but nothing ever explicitly tells it to load, so that the package never runs. There are two solutions to this, which depend on your context. First, removing the :defer t line in the use-package will certainly solve the issue, but will also load the package when emacs opens, which can slow down the startup time. More generally however, this issue can be solved by including the proper mode hooks so that the package is loaded when the proper major/minor mode is activated.

Possible Issues

For the most part, I’ve never encountered a fatal issue with use-package. Packages often will simply install and load without error. Besides issues that can arise when :defer t is used without proper care, I have discovered that, on occasion, use-package cannot find the package, returning something like File error: http://XXXXXX.el, Not Found when emacs is opening, even though the package clearly exists on MELPA. After some trial-and-error, I found that the solution to this is to manually run the following command and then restart emacs:

M-x package-refresh-contents

While not particularly elegant, this solution is only necessary once in a while, so I haven’t put in the effort to replace it with anything more clever.

In addition, I rely on AucTeX for my LaTeX document editing, however, simply including (use-package auctex :ensure t) in an emacs configuration file does not work. This is because, once installed, auctex overrides the tex package. This means that, in order to get auctex working, one must include:

(use-package tex :ensure auctex)

Examples and Further Reading

The best place to start learning more of the features of use-package is at its GitHub repository page. The readme document contains some of the most basic use cases, and a couple of simple examples for configurations. However, I found the documentation to be a little sparse when I actually went to converting my own code. The best way to get started, then is by seeing the example files of others. Fortunately, my emacs configuration files, many of which rely on use-package can be found on my GitHub page. I suggest you take a look there to get going.