The reason for putting the provide at the end rather than the beginning is the same as the reason for including the comment ;;; <library.el> ends here at the end of the file:
If it's not there, then you know that you don't have the complete file.
The comment is the human-readable version of that, and (provide 'FEATURE) is the machine-readable version....
Because it's in the coding conventions, would be one answer. :)
The provide/require/features design is quite simple. When a package requires a feature it is loaded, but only if it isn't already loaded. That is determined by checking the list of features found in features.
Packages only add their features only once they have finished loading, i.e. only ...
The point of require is not lazy-loading (that would be autoload instead). Instead, the purpose is to avoid loading the same package multiple times.
In the case of config files, which of load or require is preferable is unclear and will depend on your particular use case (but I think in most cases the difference will be negligible).
treemacs-mode is not the name of the the package. It's just 'treemacs'
:bind (("C-x M-d" . treemacs))
:custom (treemacs-width 25)
I don't know if the provide statement needs to be within the config block, but this worked for me in testing.