(I don't have an opinion on NaCl as I've never used it. My understanding is that Libsodium uses NaCl in parts, and/ or re-implements it in others.)
As far as security goes, they should both be as equally secure. As far as I know they are both opinionated in that they don't provide you with an option to use less-secure techniques. In virtually every cryptographic primitive you seek, you will only find one or two more recent and more secure (ie. best-practice). This link elaborates on some of the design decisions:
https://libsodium.gitbook.io/doc/internals#security-first
Here is a good resource on Libsodium from Paragon - if you're using PHP you'll no doubt wind up here as the standard doco is a whole bunch of 'todo':
https://paragonie.com/book/pecl-libsodium
You don't specify a language, however, I have used Libsodium successfully across numerous Linux kernels, in PHP, Python (pysodium), Javascript, Windows 8.1+, and Android 7+ (via Termux). I have also interchanged certain primitives from pysodium with another Python library called cryptography.io (which relies upon OpenSSL).
One thing I like is the way the library provides two interfaces in many circumstances: a 'generically named' function, and an explicitly named one. For example, you can call crypto_aead_xchacha20poly1305_ietf_encrypt
which explicitly defines the cipher in use, or, you can call crypto_secretbox
and allow your cryptography to be 'upgraded' in the future if a newer version emerges that modifies default behaviour.
One shortcoming I have discovered so far, at least for pysodium's use of this library, is that the api exposure for Argon2id doesn't support associated data, whereas the actual algorithm code-base in the library does:
https://github.com/jedisct1/libsodium/blob/927dfe8e2eaa86160d3ba12a7e3258fbc322909c/src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c#L136
https://github.com/jedisct1/libsodium/blob/a97ab7085fcda73f4fc7dead1a499025ceda9ecc/src/libsodium/crypto_pwhash/argon2/argon2-core.c#L470
In practice, this wasn't an issue, as I just hashed the associated data with the password - however, this might be a problem in some implementations, especially if you're producing a PBKDF in parallel with another library's so you can exchange data (in an end-to-end protocol for example). If you're using Python, you can use the argon2-cffi
implementation in most circumstances.
The lack of AES-ECB and AES-CBC ciphers has prevented me from using Libsodium exclusively on one MySQL-integration project, however, it was no drama to use cryptography.io as a bridge in that circumstance. That is how I started looking at compatibility between Libsodium and OpenSSL (via pysodium and cryptography.io).