In any case, you do absolutely need to declare the dependency in DESCRIPTION, otherwise people would install your package, and get weird bugs because they haven't installed sf. Also, if you submit to CRAN, that would be instant refusal.
Then, for your question, I think the best is to directly cite the r-pkgs book:
Don’t use library() or require(). These modify the search path, affecting what functions are available from the global environment. Instead, you should use the DESCRIPTION to specify your package’s requirements, as described in Chapter 9. This also makes sure those packages are installed when your package is installed.
The chapter 9 referred to here basically recommends your the second pattern. But note that, if you want to use the first pattern, the correct way to do it is with importing the function (or whole package) in the NAMESPACE. This is described in chapter 10. In short, in the NAMESPACE file, you can add import(sf) or importFrom(sf, st_as_sf), and then just use them in your code as if you had called library(sf). If you use Roxygen, don't miss the practical explanations in Chapter 11.
One more note: calling library(sf) is more equivalent to adding a Depends in the DESCRIPTION. There are details in chapter 10. You should almost always prefer Imports to Depends.
I would probably adopt their code into your own codebase (assuming they are open source to permit this) ; I would credit them. and hope that in the future they would release to CRAN themselves.
That's a separate discussion from the previous one. My recommendation would be to avoid it, for several reasons.
If a package is on Github, that means it did not get reviewed. When submitting to CRAN or BioConductor (or if you work in rOpenSci and publish on r-universe), there are a number of automated checks and some manual ones, so presumably packages found there can't be totally broken. From GitHub, there is no such guarantee, it's totally possible that the author will put out a half-broken package and ignore all automated checks and warnings, breaking your package in the process.
In a more extreme case, the author of the GitHub package could even be malicious and change their code to leak passwords after you start depending on it (this can happen).
Another aspect is that some people may not be able to install from github, for example as a company security policy, or that some particular context does not support installing from github (here is a Python example). You can make an explicit choice that you don't care about these use cases, and people in such a scenario simply can't use your package, but it's not an obvious choice.
And of course, if you depend on a GitHub package, you can't submit to CRAN.
If you do want to go that way, for practical purpose you can use {devtools} and the Remotes field of DESCRIPTION, as described in this vignette.
Thank you very much. The small packages are made by me and basically are R data packages. I cannot submit to CRAN because of size limitations. I developed these packages to work on my project, but are available on github for anybody to use.