They are different if the package is deferred, i.e. not loaded until it is needed. In that case
:init will be executed at the time your emacs file is first read, but
:config will be executed at the time the package is actually loaded.
In your example, the use of
mode implicitly defers loading the package. You have configured the package to be loaded the first time an html file is visited.
You could use
:demand to make sure the package is always loaded at startup, but more likely what you want to do here is put your hook in
From the docstring:
:init Code to run when `use-package' form evals.
Since you're putting this in your user-init file, that basically means it will run at startup.
:config Runs if and when package loads.
So, not run until the package is actually being loaded..
:defer Defer loading of package -- automatic if :commands, :bind, :bind*, :mode or :interpreter are used.
Note the list of things that automatically make a package deferred. Basically if you tell
use-package the conditions in which you need this package, it assumes you don't want to load it until those conditions arise.
:demand Prevent deferred loading in all cases.
Make sure the package is loaded at startup, regardless of what other options you've specified.
Revisiting this based on the recent comments... What I said above is all true, but I don't think it correctly answers the question. The root problem here is actually that
html-mode is not a package, but rather a mode defined by the package
sgml-mode. This works as expected for me:
:mode ("\\.html\\'" . html-mode)
:config (add-hook 'html-mode-hook 'turn-off-auto-fill))
In the original example, the
:config expression never gets evaluated because a package named
html-mode never gets loaded. Moving the same expression to
:init works because init code is always evaluated, regardless of whether the package ever gets loaded.