I've been updating all my use-package calls now that :idle is no longer a decent way to defer stuff. At the moment one of the biggest hits on my load time is elpy which loads a whole bunch of additional modules. At the moment my invocation is rather basic:

(use-package elpy
  :commands elpy-enable
  :init (elpy-enable)
    (setq elpy-rpc-backend "jedi"
          elpy-rpc-project-specific 't)
    (when (fboundp 'flycheck-mode)
      (setq elpy-modules (delete 'elpy-module-flymake elpy-modules)))))

However this is rather wasteful if I'm never editing any python modules. The trouble is elpy is a collection of modes so I can't just use the mode binding form as elpy-enable needs to get called. So what approach should I use. Is it just a case of triggering on the python-mode hook?

  • I just stopped tracking the MELPA version of use-package. It seems :idle was removed with nothing to replace it. I'll just wait until a replacement pops up.
    – abo-abo
    Commented Mar 17, 2015 at 9:21
  • @abo-abo: I can understand why, :idle is a bit of a hack. Really for proper on-demand loading it should be triggered by an event other than "some time passed".
    – stsquad
    Commented Mar 17, 2015 at 10:02
  • 2
    :idle can be replaced with something like :defer 30 where the number is the delay in seconds after which the package should be loaded. Commented Mar 17, 2015 at 10:39
  • @kaushalmodi, does that already work?
    – abo-abo
    Commented Mar 17, 2015 at 10:40
  • @abo-abo I haven't tried but it probably should. I read that update in yesterday's commit. The README is also updated with that info. Commented Mar 17, 2015 at 10:41

3 Answers 3


I don’t know Elpy, so I’m not sure whether I understand your problem correctly. I do know use-package, though, and recently suffered from the very same issue, namely the removal of :idle.

Basically, there are two ways out, depending on how you need to use Elpy. You can either use a poor man’s :idle, with run-with-idle-timer, e.g.

:init (run-with-idle-timer 10 nil #'elpy-enable)

Alternatively, you can rely on good old with-eval-after-load or use python-mode-hook and delay Elpy until after Python Mode is loaded or enabled respectively:

:init (add-hook 'python-mode-hook #'elpy-enable)
;; or
:init (with-eval-after-load 'python (elpy-enable))
  • If elpy was a simple mode it would be fine. However really it's a bunch of minor-modes stitched together to make the python experience more integrated. As such the elpy-enable step has to be run before the first python file is loaded so all the modules are configured and ready.
    – stsquad
    Commented Mar 17, 2015 at 20:48
  • @stsquad with-eval-after-load should do exactly that.
    – user227
    Commented Mar 17, 2015 at 21:15
  • 1
    I need to add :commands elpy-enable to make it works. :init (with-eval-after-load 'python (elpy-enable)) :commands elpy-enable
    – azzamsa
    Commented Oct 30, 2018 at 5:06

The author of elpy suggests doing this via an advice, because elpy-enable modifies the python-mode-hook variable, so calling it inside the mode-hook is too late.

simple approach:

(advice-add 'python-mode :before 'elpy-enable)

using use-package:

(use-package elpy :ensure t
  :defer t
  (advice-add 'python-mode :before 'elpy-enable))

I think it is possible with :after

(use-package python
  :ensure t
  :defer t
  :mode ("\\.py\\'" . python-mode))

(use-package elpy
  :ensure t
  :after python
  :config (elpy-enable))

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.