I've added a line in my early-init.el file that sets a background color to prevent the glare during startup.

;; Customize background color to prevent startup glare
(add-to-list 'default-frame-alist
             '(background-color . "#fff2f3"))

However, I've noticed that the code can also be written as:

;; Customize background color to prevent startup glare
(push '(background-color . "#fff2f3") default-frame-alist)

They both achieve the same result. I was wondering if there is any disadvantage in using one method over the other?

  • 1
    add-to-list checks by default if the element to be added exists already in the list and, if so, it does not add it again. push does not check. The doc string for add-to-list suggests that it is useful for config variables (like default-frame-alist above) where the uniqueness might be important, but recommends that push be used in Lisp code in general: C-h f add-to-list.
    – NickD
    Jul 20, 2023 at 11:46
  • During early startup I don't think it matters then which one I use. The default-frame-alist is empty.
    – Zoli
    Jul 20, 2023 at 11:49
  • push is usually faster in such cases. Fastest: (setq YOUR/LIST (cons NEW-ELT YOUR/LIST)). Actually, the choice doesn't make much of a difference. Just choose one depending on your preference.
    – shynur
    Jul 20, 2023 at 11:56
  • @shynur: That's the same as push -- it expands to the same code (where appropriate).
    – phils
    Jul 20, 2023 at 12:22
  • @phils: Yes, but macro-expansion takes some time when loading *.el, although it's little.
    – shynur
    Jul 20, 2023 at 13:52

1 Answer 1


The doc makes clear what the differences are.

If you obtain the variable (its symbol) programmatically, i.e., you evaluate something to get the symbol, then use add-to-list. (Otherwise, with push you need to invoke eval to get the value of the resulting symbol.)

push adds a list element unconditionally; add-to-list adds an element only if not already in the list. However, you can use macro cl-pushnew to add an element only if not already present.

In Elisp, push doesn't let you provide the equivalent of add-to-list's args APPEND and COMPARE-FN. However, you can use macro cl-pushnew to get the effect of both.

The differences generally don't matter for the use case you describe: simply adding an element to a configuration variable in your init file. (If it matters to you whether the element is added if it's already present, then use add-to-list or cl-pushnew.)

Generally speaking add-to-list is more similar to cl-pushnew than it is to push.

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.