If you write your promises code not to cause explicit side effects - it won't and you get pure code.
The fact you have (controlled!) side effects is the whole purpose of the IO monad. You can't avoid side effects or your program wouldn't do anything, a promise keeps the side effects in a box (the promise) and lets you code using boxes so that your code is purer. Of course, not all your code can be _actually_ pure because all code needs side effects.
The FUD about async/await is even stranger. JS _has_ async/await, it already shipped in Microsoft Edge (IE) and it's coming to other browsers. It is based on promises (just like it's based on Tasks = Promises) in C#.
The fact people talk so much about this without learning the topic is amazing. I'm genuinely disappointed with the quality of discussion in HN over these topics lately.
Monet is also a bad implementation of the IO monad in JS, in fact it's not an implementation at all. Here is an issue I opened there a while ago: https://github.com/cwmyers/monet.js/issues/25
[1] up to the fact `.then` does both `fmap` and `>>=` through overloading based on the return type. Seriously, if you remove the exceptions and the fact you can return an unwrapped value it's `Promise a -> a -> Promise b -> Promise b` for then's signature (the Promise a being `this`, the a -> Promise b` being the handler and the return value being itself).