The traditional way: separating data and code
document.createElement("h1").textContent = `Hello, ${username}!`
If you allow <h1> in the setHTML configuration or use the default, users with the tag in their username also always get it rendered as markup
It sounds like you're arguing against a specific usecase, rather than the technology itself. If you don't want arbitrary markup in usernames, setHTML would absolutely be the wrong choice, but that's not really a good argument against setHTML.
Which is why you only use it where you want to allow some kind of html..?