             ((not mode)
              (error "No namespace specified on `doom!' for %s" p))
             (t
-             (setq doom-modules (append doom-modules (list (cons mode p))))))))
-  (unless doom--dont-load-p
-    `(let (file-name-handler-alist)
+             (setq doom-enabled-modules (append doom-enabled-modules (list (cons mode p))))))))
+  `(unless noninteractive
+     (let (file-name-handler-alist)
        ,@(mapcar (lambda (pkg) (macroexpand `(load! ,(car pkg) ,(cdr pkg))))
-                 doom-modules)
-
-       (unless noninteractive
-         (when (display-graphic-p)
-           (require 'server)
-           (unless (server-running-p)
-             (server-start)))
-
-         ;; Prevent any auto-displayed text + benchmarking
-         (advice-add 'display-startup-echo-area-message :override 'ignore)
-         (message "Loaded %s packages in %s"
-                  (length doom-packages)
-                  (emacs-init-time))))))
+                 doom-enabled-modules)
+
+       (when (display-graphic-p)
+         (require 'server)
+         (unless (server-running-p)
+           (server-start)))
+
+       ;; Prevent any auto-displayed text + benchmarking
+       (advice-add 'display-startup-echo-area-message :override 'ignore)
+       (message "Loaded %s packages in %s"
+                (- (length load-path) (length doom--load-path))
+                (emacs-init-time)))))
 
 (defun doom-initialize (&optional force-p)
-  "Initialize installed packages (using package.el). On first run it will
-prepare Emacs to auto-install all missing packages. If you byte compile
-core/core.el, calls to `package.el' are avoided to speed up startup."
+  "Initialize installed packages (using package.el) and ensure the core packages
+are installed. If you byte compile core/core.el, calls to `package.el' are
+avoided to speed up startup."
   (unless (or doom--init force-p)
     (setq load-path doom--load-path
           package-activated-list nil)
     (package-initialize)
-    (unless (package-installed-p 'quelpa-use-package)
+    (unless (and (file-exists-p doom-packages-dir)
+                 (require 'quelpa-use-package nil t))
       (package-refresh-contents)
-      (package-install 'quelpa-use-package t)
-      (setq doom--auto-install-p (not noninteractive)))
-    (unless (featurep 'quelpa-use-package)
-      (require 'quelpa-use-package)
-      (quelpa-use-package-activate-advice)
-      (setq use-package-expand-minimally t)
-      ;; Move :ensure to after conditional properties
-      (delq :ensure use-package-keywords)
-      (push :ensure (cdr (memq :unless use-package-keywords))))
+      ;; Ensure core packages are installed
+      (mapc 'package-install '(quelpa-use-package dash f s)))
+    (unless (require 'quelpa-use-package nil t)
+      (delete-directory doom-packages-dir t)
+      (error "There was an error initializing DOOM. Try running it again"))
+    (quelpa-use-package-activate-advice)
+    ;; Move :ensure to after conditional properties
+    (delq :ensure use-package-keywords)
+    (push :ensure (cdr (memq :unless use-package-keywords)))
     (setq doom--init t)))
 
+(defun doom-reload-modules ()
+  "Reload `doom-modules'."
+  (setq doom-modules nil)
+  (let ((doom--prefer-el-p t)
+        (noninteractive t))
+    (load (concat doom-emacs-dir "init.el") nil :nomessage :nosuffix)))
+
+(defun doom-reload-packages (&optional install-p)
+  "Reload `doom-packages'."
+  (doom-initialize)
+  (doom-reload-modules)
+  (let ((before-packages-n (length package-alist))
+        (doom--auto-install-p (and install-p t))
+        (doom--prefer-el-p t)
+        (after-packages-n 0)
+        noninteractive)
+    (when doom--auto-install-p
+      (package-refresh-contents))
+    (load (f-expand "core.el" doom-core-dir) nil (not doom-debug-mode) :nosuffix)
+    (mapc (lambda (pkg)
+            (let ((path (f-expand "packages.el" (doom-module-path (car pkg) (cdr pkg)))))
+              (when (f-exists-p path)
+                (load path nil (not doom-debug-mode) :nosuffix))))
+          doom-enabled-modules)
+    (- (length package-alist) before-packages-n)))
+
 
 ;;
 ;; Macros
 ;;
 
-(defvar doom--packages nil
-  "List of packages explicitly installed during this session.")
-
-(defalias 'use-package! 'use-package
-  "To adhere to the naming conventions of DOOM emacs.")
+(defvar __DIR__ nil  "The directory of the currently loaded file (set by `load!')")
+(defvar __FILE__ nil "The full path of the currently loaded file (set by `load!')")
+
+(defmacro use-package! (name &rest plist)
+  "A `use-package' wrapper, to adhere to the naming conventions of DOOM emacs
+and let-bind `package-name' for the containing forms. Note that packages are
+deferred by default."
+  (macroexpand
+   `(let ((package-name ',name))
+      (use-package ,name ,@plist))))
 
 (defmacro package! (name &rest plist)
   "Wraps around `use-package' (with `quelpa-use-package') and takes the same
 arguments. Ensures the package named NAME is installed and available. If
 `doom--auto-install-p' is nil, then strip out :ensure and :quelpa properties,
-which is the case if you've byte-compiled DOOM Emacs."
+which is the case if you've byte-compiled DOOM Emacs.
+
+Note that packages are deferred by default."
   (declare (indent defun))
   (let ((use-package-always-ensure doom--auto-install-p)
         (recipe (plist-get plist :quelpa)))

a lot from this."
  (interactive)
  (doom-initialize)
  (let ((targets (append (list (f-expand "init.el" doom-emacs-dir)
                               (f-expand "core.el" doom-core-dir))
                         (reverse (f-glob "core-*.el" doom-core-dir))
                         (-filter 'f-exists-p
                                  (--map (doom-module-path (car it) (cdr it) "config.el")
                                         doom-modules))))
        use-package-always-ensure
        file-name-handler-alist)
    (mapc 'byte-compile-file targets)
    (when noninteractive
      (when targets (message "\n"))
      (message "Compiled %s files:\n%s" (length targets)
               (mapconcat (lambda (file) (concat "+ " (f-relative file doom-emacs-dir)))
                          targets "\n")))))

(defun doom/refresh-autoloads ()
  "Refreshes the autoloads.el file, which tells Emacs where to find all the
autoloaded functions in the modules you use or among the core libraries.

Rerun this whenever you modify your init.el (or use `make autoloads` from the
command line)."
  (interactive)
  ;; Reload modules (don't load anything)
  (setq doom-modules nil)
  (let ((doom--dont-load-p t)
        (noninteractive t))
    (load (concat doom-emacs-dir "init.el") nil :nomessage t))

  (let ((generated-autoload-file (concat doom-local-dir "autoloads.el"))
        (autoload-files
         (append
          (-flatten (mapcar (lambda (m)
                              (let* ((dir (doom-module-path (car m) (cdr m)))
                                     (auto-dir (f-expand "autoload" dir))
                                     (auto-file (f-expand "autoload.el" dir)))
                                (cond ((f-directory-p auto-dir)
                                       (f-glob "*.el" auto-dir))
                                      ((f-exists-p auto-file)
                                       auto-file))))
                            doom-modules))
          (f-glob "autoload/*.el" doom-core-dir))))
    (when (f-exists-p generated-autoload-file)
      (delete-file generated-autoload-file)
      (when noninteractive (message "Deleted old autoloads.el")))
    (dolist (file autoload-files)
      (update-file-autoloads file)
      (when noninteractive
        (message "Detected: %s" (f-relative file doom-emacs-dir))))
    (with-current-buffer (get-file-buffer generated-autoload-file)
      (save-buffer))
    (when noninteractive (message "Done!"))
    (with-demoted-errors "WARNING: %s"
      (load generated-autoload-file nil t))))

(provide 'core-packages)
;;; core-packages.el ends here

  "If non-nil, install missing packages. Otherwise, strip :ensure and :quelpa
from `package!' calls.")

(defvar doom--prefer-el-p (or noninteractive doom--auto-install-p)
  "If non-nil, load uncompiled .el config files.")

(defvar doom--load-path (append (list doom-core-dir
                                      doom-modules-dir)
