I have a package that enhances the functionality of another package. To save the user the effort of any additional configurating, I would like my package to load automatically if the larger package loads.

(In my example, my package is a Flycheck checker, but I don’t think this situation will be specific to Flycheck checkers).

Is there a standard idiom for achieving this?

I find myself tempted to put the following at the end of my package:

(with-eval-after-load 'flycheck
  (unless (featurep 'flycheck-mychecker)
    (require 'flycheck-mychecker)))

Now, package-lint tells me:

warning: `with-eval-after-load' is for use in configurations, and should rarely be used in packages

However, I couldn’t find an explanation of why this is typically bad in packages, and in what circumstances the “rarely used” exception should apply.

1 Answer 1

  1. Use autoload for specific commands etc.

  2. Use require if your library depends on another. That's the main question to ask yourself: does your library need the other library? If so, require it.

    You can also use a "soft-require" if you want to load another library whenever something is true. For example:

(when (fboundp 'foobar) (require 'foo nil t))
  1. Use with-eval-after-load (or eval-after-load) if you want to do something after some other library is loaded:
(with-eval-after-load 'bar
  ;; ...

I imagine that the "rarely used" just means that most libraries explicitly use require or they autoload stuff. The doc of with-eval-after-load and eval-after-load describes their behavior, which in turn defines their use cases. Don't use them when you don't need them; that's all I think that "rarely used" intends.

On the other hand, presumably your package is intended to be optional. In that case, it's enough that a user explicitly loads it. And in that case all you need to do is require the larger package at the outset of your code. I imagine that this is also part of what the text you quote intends.

A final note. If you want to load a library again, or load a library with the same name as one that's already been loaded (e.g. to pick up some other variant of version of it), then use load-library, not require. And if you want to load the source file (*.el) then explicitly include the .el in the argument to load-library.

  • "presumably your package is intended to be optional" -- I admit that wasn't my intention. I'd expect a user to want to configure which major modes a Flycheck checker applies to (which they can via customization), but I find it surprising that a user might want to install a package but never load it.
    – mavit
    Aug 7, 2021 at 20:53
  • @mavit: It's optional whether to download, install, and load a package. Using a package (in any way) is a user choice - that was my point.
    – Drew
    Aug 8, 2021 at 0:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.