use-package</a> is an
Emacs</a> package which allows
packages to be loaded declaratively. It's been around for ages and
I've seen it used in other people's configurations, but I've only
recently paid some real attention to it. I wish I'd learned how to use
it sooner - it's really improved my Emacs config</a>.</p>
Let's look at an example:</p>
When this is run, the use of the Magit</a> package is declared and
two key-bindings for its main function are defined. What's really nice
here is that autoloads are installed for those key-bindings - the
package isn't actually loaded until I actually type either of those
shortcuts for the first time. This means Emacs can start faster and
resources aren't used for features I don't use often (that said, Magit is
something I do use all</em> the time!).</p>
Note use-package's clear, compact syntax. There's less ceremony for
common startup tasks such as setting up key-bindings and I love how
use-package encourages all setup related to a given package to be
neatly grouped together.</p>
It's common to need to run some code before or after a package is
loaded in order to set it up. With use-package this is done using
Again, because loading of the package is deferred until one of the
key-bindings is used, the messages won't appear until I actually hit
one of those keys.</p>
Key-bindings are just one way that a deferred package might be loaded
by use-package. Other mechanisms include assigning a file extension to
a mode defined in the package (via Of course there are some packages which you always want to be loaded
immediately. use-package can handle this too through the Here we have the Evil</a> package
being loaded immediately (due to the Note the use of the In the previous example, the key-binding is slightly different to
earlier examples because the binding is being set inside a specific
keymap instead of globally. use-package provides clean syntax for
this. Here's an example with multiple key-bindings being set up across
multiple keymaps:</p>
Not bad! Much better than:</p>
By default, use-package only loads packages that have already
installed somehow, but it can integrate with a package manager too.</p>
If you're already using the built-in Emacs package manager
(package.el</a>)
then simply adding This avoids the need to separately call package.el's use-package can also work with other package managers. The powerful
straight.el</a> package
manager has tight integration with use-package (it's what I use now).</p>
If you want to learn more about use-package, the official
README</a>
is approachable and comprehensive. There's plenty more to it than what
I've covered here, although you don't need to know much to start see
its benefits.</p>
Other articles that you might also find helpful:</p>
(use-package magit</span></span>
:bind (("C-x g" . magit-status)</span></span>
("C-x C-g" . magit-status)))</span></span></code></pre>
Configuring Packages</h4>
:init</code> (before loading) and :config</code> (after loading). Here's the
above example with some "helpful" messages inserted printed before and
after the magit package is loaded:</p>
(use-package magit</span></span>
:init</span></span>
(message "Loading Magit!")</span></span>
:config</span></span>
(message "Loaded Magit!")</span></span>
:bind (("C-x g" . magit-status)</span></span>
("C-x C-g" . magit-status)))</span></span></code></pre>
Deferred Loading</h4>
:mode</code>) or by adding a function
from the package into a hook (via :hook</code>). use-package provides
a variety of syntactic sugar to make this painless and concise.</p>
Immediate Loading</h4>
:demand</code>
keyword. Here's an example:</p>
(use-package evil</span></span>
:demand t</span></span>
</span>
:custom</span></span>
(evil-esc-delay 0.001 "avoid ESC/meta mixups")</span></span>
(evil-shift-width 4)</span></span>
(evil-search-module 'evil-search)</span></span>
</span>
:bind (:map evil-normal-state-map</span></span>
("S" . replace-symbol-at-point))</span></span>
</span>
:config</span></span>
;; Enable evil-mode in all buffers.</span></span>
(evil-mode 1))</span></span></code></pre>
:demand t</code>) with some configuration
set before it's loaded (some customisations need to be set before
loading), a key-binding added, and evil-mode being enabled globally.</p>
:custom</code> keyword here. This is a clean way of
setting customisations that you could also set with Emacs' customize
functionality. It can be nice to keep customizations with the
use-package declaration, although I'm not that consistent about this
myself.</p>
Key-bindings in Keymaps</h4>
(use-package evil-args</span></span>
:bind (:map evil-inner-text-objects-map</span></span>
("a" . evil-inner-arg)</span></span>
:map evil-outer-text-objects-map</span></span>
("a" . evil-outer-arg)</span></span>
</span>
:map evil-normal-state-map</span></span>
("L" . evil-forward-arg)</span></span>
("K" . evil-jump-out-args)</span></span>
</span>
:map evil-normal-state-map</span></span>
("H" . evil-backward-arg)</span></span>
("L" . evil-forward-arg)</span></span>
</span>
:map evil-motion-state-map</span></span>
("H" . evil-backward-arg)</span></span>
("L" . evil-forward-arg)))</span></span></code></pre>
(define-key evil-inner-text-objects-map (kbd "a") 'evil-inner-arg)</span></span>
(define-key evil-outer-text-objects-map (kbd "a") 'evil-outer-arg)</span></span>
(define-key evil-normal-state-map (kbd "L") 'evil-forward-arg)</span></span>
; you get the idea ...</span></span></code></pre>Package Manager Integration</h4>
:ensure t</code> to a use-package</code> block will cause
use-package to download and install the package if it's not already
there. Extending our first example slightly:</p>
(use-package magit</span></span>
:ensure t</span></span>
:bind (("C-x g" . magit-status)</span></span>
("C-x C-g" . magit-status)))</span></span></code></pre>
install-package</code>
function or use the list-packages</code> interface to install a package.</p>
What Next?</h4>
This page cannot be shown here. You can still read it on the original site — the toolbar below keeps your place in the directory.
use-package is an Emacs package which allows packages to be loaded declaratively. It's been around for ages and I've seen it used in other people's configurations, but I've only recently paid some real attention to it. I wish I'd learned how to use it sooner - it's really improved my Emacs config . Let's look at an example: (use-package magit :bind (("C-x g" .…
Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.