3.5 Loading packages in sequence

Sometimes it only makes sense to configure a package after another one has been loaded, because certain variables or functions are not in scope until that time. This can be achieved with the :after keyword, which allows a fairly rich description of the exact conditions when loading should occur. The :after keyword takes as argument either a symbol indicating the package name, a list of such symbols, or a list of selectors (see below).

Here is an example of using the GNU ELPA packages hydra, ivy, and ivy-hydra. Note that ivy-hydra will always be loaded last:

(use-package hydra)

(use-package ivy)

(use-package ivy-hydra
  :after (ivy hydra))

In this case, because the declarations are evaluated in the order they occur, the use of :after is not strictly necessary. However, if ‘hydra’ and ‘ivy’ were to be autoloaded, using :after guarantees that ‘ivy-hydra’ is not loaded until it is actually needed. By using :after, the above code will also work even if the order of the declaration changes. This means that moving things around in your init file is less likely to break things.

Using :after selectors

The :after keyword also accepts a list of selectors. By default, :after (foo bar) is the same as :after (:all foo bar), meaning that loading of the given package will not happen until both foo and bar have been loaded. Here are some of the other possibilities:

:after (foo bar)
:after (:all foo bar)
:after (:any foo bar)
:after (:all (:any foo bar) (:any baz quux))
:after (:any (:all foo bar) (:all baz quux))

When you nest selectors, such as in (:any (:all foo bar) (:all baz quux)), it means that the package will be loaded when either both foo and bar have been loaded, or when both baz and quux have been loaded.

Pay attention when setting use-package-always-defer to a non-nil value, and also using the :after keyword. In that case, you will need to specify how the declared package is to be loaded: for example, by some :bind (see Global keybindings). If you are not using one of the keywords that registers autoloads, such as :bind or :hook (see Hooks), and your package manager does not provide autoloads, it is possible that your package will never be loaded if you do not add :demand t to those declarations.